Пример #1
0
int main(int argc, char **argv)
{
    ncMetadata meta = { "correlate-me-please", "eucalyptus" };
    virtualMachine params = { 64, 1, 1, "m1.small", NULL, NULL, NULL, NULL, NULL, {}, 0 };
    char *nc_hostport = DEFAULT_NC_HOSTPORT;
    char *walrus_hostport = DEFAULT_WALRUS_HOSTPORT;
    char *instance_id = NULL;
    char *image_id = NULL;
    char *image_manifest = NULL;
    char *kernel_id = NULL;
    char *kernel_manifest = NULL;
    char *ramdisk_id = NULL;
    char *ramdisk_manifest = NULL;
    char *reservation_id = NULL;
    char *uu_id = NULL;
    char *mac_addr = strdup(DEFAULT_MAC_ADDR);
    char *public_ip = strdup(DEFAULT_PUBLIC_IP);
    char *volume_id = NULL;
    char *remote_dev = NULL;
    char *local_dev = NULL;
    int force = 0;
    char *user_data = NULL;
    char *launch_index = NULL;
    char **group_names = NULL;
    int group_names_size = 0;
    char *timestamp_str = NULL;
    char *command = NULL;
    int local = 0;
    int count = 1;
    int ch;

    while ((ch = getopt(argc, argv, "lhdn:w:i:m:k:r:e:a:c:h:u:p:V:R:L:FU:I:G:v:t:")) != -1) {
        switch (ch) {
        case 'c':
            count = atoi(optarg);
            break;
        case 'd':
            debug = 1;
            break;
        case 'l':
            local = 1;
            break;
        case 'n':
            nc_hostport = optarg;
            break;
        case 'w':
            walrus_hostport = optarg;
            break;
        case 'i':
            instance_id = optarg;
            break;
        case 'p':
            public_ip = optarg;
            break;
        case 'm':
            image_id = strtok(optarg, ":");
            image_manifest = strtok(NULL, ":");
            if (image_id == NULL || image_manifest == NULL) {
                fprintf(stderr, "ERROR: could not parse image [id:manifest] paramters (try -h)\n");
                exit(1);
            }
            break;
        case 'k':
            kernel_id = strtok(optarg, ":");
            kernel_manifest = strtok(NULL, ":");
            if (kernel_id == NULL || kernel_manifest == NULL) {
                fprintf(stderr, "ERROR: could not parse kernel [id:manifest] paramters (try -h)\n");
                exit(1);
            }
            break;
        case 'r':
            ramdisk_id = strtok(optarg, ":");
            ramdisk_manifest = strtok(NULL, ":");
            if (ramdisk_id == NULL || ramdisk_manifest == NULL) {
                fprintf(stderr, "ERROR: could not parse ramdisk [id:manifest] paramters (try -h)\n");
                exit(1);
            }
            break;
        case 'e':
            reservation_id = optarg;
            break;
        case 'u':
            uu_id = optarg;
            break;
        case 'a':
            mac_addr = optarg;
            break;
        case 'V':
            volume_id = optarg;
            break;
        case 'R':
            remote_dev = optarg;
            break;
        case 'L':
            local_dev = optarg;
            break;
        case 'F':
            force = 1;
            break;
        case 'U':
            user_data = optarg;
            break;
        case 'I':
            launch_index = optarg;
            break;
        case 'G':
            {
                int i;
                group_names_size = 1;
                for (i = 0; optarg[i]; i++)
                    if (optarg[i] == ':')
                        group_names_size++;
                group_names = malloc(sizeof(char *) * group_names_size);
                if (group_names == NULL) {
                    fprintf(stderr, "ERROR: out of memory for group_names[]\n");
                    exit(1);
                }
                group_names[0] = strtok(optarg, ":");
                for (i = 1; i < group_names_size; i++)
                    group_names[i] = strtok(NULL, ":");
                break;
            }
        case 'v':
            if (add_vbr(optarg, &params)) {
                fprintf(stderr, "ERROR: could not parse the virtual boot record (try -h)\n");
                exit(1);
            }
            break;
        case 't':
            timestamp_str = optarg;
            break;
        case 'h':
            usage();            // will exit
        case '?':
        default:
            fprintf(stderr, "ERROR: unknown parameter (try -h)\n");
            exit(1);
        }
    }
    argc -= optind;
    argv += optind;

    if (argc > 0) {
        command = argv[0];
        if (argc > 1) {
            fprintf(stderr, "WARNING: too many parameters, using first one as command\n");
        }
    } else {
        fprintf(stderr, "ERROR: command not specified (try -h)\n");
        exit(1);
    }

    ncStub *stub;
    char configFile[1024], policyFile[1024];
    char *euca_home;
    int rc, use_wssec;
    char *tmpstr;

    euca_home = getenv("EUCALYPTUS");
    if (!euca_home) {
        euca_home = "";
    }
    snprintf(configFile, 1024, EUCALYPTUS_CONF_LOCATION, euca_home);
    snprintf(policyFile, 1024, EUCALYPTUS_KEYS_DIR "/nc-client-policy.xml", euca_home);
    rc = get_conf_var(configFile, "ENABLE_WS_SECURITY", &tmpstr);
    if (rc != 1) {
        /* Default to enabled */
        use_wssec = 1;
    } else {
        if (!strcmp(tmpstr, "Y")) {
            use_wssec = 1;
        } else {
            use_wssec = 0;
        }
    }

    char nc_url[BUFSIZE];
    snprintf(nc_url, BUFSIZE, "http://%s%s", nc_hostport, NC_ENDPOINT);
    if (debug)
        printf("connecting to NC at %s\n", nc_url);
    stub = ncStubCreate(nc_url, "NCclient.log", NULL);
    if (!stub) {
        fprintf(stderr, "ERROR: failed to connect to Web service\n");
        exit(2);
    }

    char walrus_url[BUFSIZE];
    snprintf(walrus_url, BUFSIZE, "http://%s%s", walrus_hostport, WALRUS_ENDPOINT);
    serviceInfoType *si = &(meta.services[meta.servicesLen++]);
    safe_strncpy(si->type, "walrus", sizeof(si->type));
    safe_strncpy(si->name, "walrus", sizeof(si->name));
    safe_strncpy(si->uris[0], walrus_url, sizeof(si->uris[0]));
    si->urisLen = 1;

    if (use_wssec && !local) {
        if (debug)
            printf("using policy file %s\n", policyFile);
        rc = InitWSSEC(stub->env, stub->stub, policyFile);
        if (rc) {
            fprintf(stderr, "ERROR: cannot initialize WS-SEC policy from %s\n", policyFile);
            exit(1);
        }
    }

    char *image_url = NULL;
    if (image_manifest) {
        char t[BUFSIZE];
        snprintf(t, BUFSIZE, "http://%s%s/%s", walrus_hostport, WALRUS_ENDPOINT, image_manifest);
        image_url = strdup(t);
    }

    char *kernel_url = NULL;
    if (kernel_manifest) {
        char t[BUFSIZE];
        snprintf(t, BUFSIZE, "http://%s%s/%s", walrus_hostport, WALRUS_ENDPOINT, kernel_manifest);
        kernel_url = strdup(t);
    }

    char *ramdisk_url = NULL;
    if (ramdisk_manifest) {
        char t[BUFSIZE];
        snprintf(t, BUFSIZE, "http://%s%s/%s", walrus_hostport, WALRUS_ENDPOINT, ramdisk_manifest);
        ramdisk_url = strdup(t);
    }

    /***********************************************************/
    if (!strcmp(command, "runInstance")) {
        if (params.virtualBootRecordLen < 1) {
            CHECK_PARAM(image_id, "image ID and manifest path");
            CHECK_PARAM(kernel_id, "kernel ID and manifest path");
        }

        char *privMac, *pubMac, *privIp;
        char *platform = NULL;
        int vlan = 3;
        privMac = strdup(mac_addr);
        mac_addr[0] = 'b';
        mac_addr[1] = 'b';
        privIp = strdup("10.0.0.202");
        srand(time(NULL));

        /* generate random IDs if they weren't specified */
#define C rand()%26 + 97

        while (count--) {
            char *iid, *rid, *uuid;

            char ibuf[8];
            if (instance_id == NULL || count > 1) {
                snprintf(ibuf, 8, "i-%c%c%c%c%c", C, C, C, C, C);
                iid = ibuf;
            } else {
                iid = instance_id;
            }

            char rbuf[8];
            if (reservation_id == NULL || count > 1) {
                snprintf(rbuf, 8, "r-%c%c%c%c%c", C, C, C, C, C);
                rid = rbuf;
            } else {
                rid = reservation_id;
            }

            char ubuf[48];
            if (uu_id == NULL || count > 1) {
                snprintf(ubuf, 48, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
                         C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C);
                uuid = ubuf;
            } else {
                uuid = uu_id;
            }

            netConfig netparams;
            ncInstance *outInst;
            bzero(&netparams, sizeof(netparams));
            netparams.vlan = vlan;
            snprintf(netparams.privateIp, 24, "%s", privIp);
            snprintf(netparams.privateMac, 24, "%s", privMac);

            int rc = ncRunInstanceStub(stub, &meta,
                                       uuid, iid, rid,
                                       &params,
                                       image_id, image_url,
                                       kernel_id, kernel_url,
                                       ramdisk_id, ramdisk_url,
                                       "eucalyptusUser", "eucalyptusAccount",
                                       "",  /* key */
                                       &netparams,
                                       //                                       privMac, privIp, vlan, 
                                       user_data, launch_index, platform, 0, group_names, group_names_size, /* CC stuff */
                                       &outInst);
            if (rc != 0) {
                printf("ncRunInstance() failed: instanceId=%s error=%d\n", instance_id, rc);
                exit(1);
            }
            // count device mappings
            int i, count = 0;
            for (i = 0; i < EUCA_MAX_VBRS; i++) {
                if (strlen(outInst->params.virtualBootRecord[i].typeName) > 0)
                    count++;
            }
            printf("instanceId=%s stateCode=%d stateName=%s deviceMappings=%d/%d\n", outInst->instanceId, outInst->stateCode, outInst->stateName,
                   count, outInst->params.virtualBootRecordLen);
        }

        /***********************************************************/
    } else if (!strcmp(command, "bundleInstance")) {
        CHECK_PARAM(instance_id, "instance id");
        int rc =
            ncBundleInstanceStub(stub, &meta, instance_id, "bucket-foo", "prefix-foo", "s3-url-foo", "user-key-foo", "s3policy-foo", "s3policy-sig");
        printf("ncBundleInstanceStub = %d\n", rc);

    } else if (!strcmp(command, "bundleRestartInstance")) {
        CHECK_PARAM(instance_id, "instance id");
        int rc = ncBundleRestartInstanceStub(stub, &meta, instance_id);
        printf("ncBundleRestartInstanceStub = %d\n", rc);
    } else if (!strcmp(command, "powerDown")) {
        int rc = ncPowerDownStub(stub, &meta);
    } else if (!strcmp(command, "describeBundleTasks")) {
        char *instIds[4];
        int instIdsLen;
        instIds[0] = malloc(sizeof(char) * 32);
        instIds[1] = malloc(sizeof(char) * 32);
        instIds[2] = malloc(sizeof(char) * 32);
        instIds[3] = malloc(sizeof(char) * 32);
        snprintf(instIds[0], 32, "i-12345675");
        snprintf(instIds[1], 32, "i-12345674");
        snprintf(instIds[2], 32, "i-12345673");
        snprintf(instIds[3], 32, "i-12345672");
        instIdsLen = 4;
        bundleTask **outBundleTasks = NULL;
        int outBundleTasksLen = 0;
        rc = ncDescribeBundleTasksStub(stub, &meta, instIds, instIdsLen, &outBundleTasks, &outBundleTasksLen);
        for (int i = 0; i < outBundleTasksLen; i++) {
            printf("BUNDLE %d: %s %s\n", i, outBundleTasks[i]->instanceId, outBundleTasks[i]->state);
        }
    } else if (!strcmp(command, "assignAddress")) {
        int rc = ncAssignAddressStub(stub, &meta, instance_id, public_ip);
    } else if (!strcmp(command, "terminateInstance")) {
        CHECK_PARAM(instance_id, "instance ID");

        int shutdownState, previousState;
        int rc = ncTerminateInstanceStub(stub, &meta, instance_id, 0, &shutdownState, &previousState);
        if (rc != 0) {
            printf("ncTerminateInstance() failed: error=%d\n", rc);
            exit(1);
        }
        printf("shutdownState=%d, previousState=%d\n", shutdownState, previousState);

        /***********************************************************/
    } else if (!strcmp(command, "describeInstances")) {
        /* TODO: pull out of argv[] requested instanceIDs */
        ncInstance **outInsts;
        int outInstsLen, i;
        int rc = ncDescribeInstancesStub(stub, &meta, NULL, 0, &outInsts, &outInstsLen);
        if (rc != 0) {
            printf("ncDescribeInstances() failed: error=%d\n", rc);
            exit(1);
        }
        for (i = 0; i < outInstsLen; i++) {
            ncInstance *inst = outInsts[i];
            printf("instanceId=%s state=%s time=%d\n", inst->instanceId, inst->stateName, inst->launchTime);
            if (debug) {
                printf("              userData=%s launchIndex=%s groupNames=", inst->userData, inst->launchIndex);
                if (inst->groupNamesSize > 0) {
                    int j;
                    for (j = 0; j < inst->groupNamesSize; j++) {
                        if (j > 0)
                            printf(":");
                        printf("%s", inst->groupNames[j]);
                    }
                } else {
                    printf("(none)");
                }
                printf("\n");

                printf("              attached volumes: ");
                int vol_count = 0;
                for (int j = 0; j < EUCA_MAX_VOLUMES; j++) {
                    if (strlen(inst->volumes[j].volumeId) > 0) {
                        if (vol_count > 0)
                            printf("                                ");
                        printf("%s %s %s\n", inst->volumes[j].volumeId, inst->volumes[j].remoteDev, inst->volumes[j].localDev);
                    }
                }
                if (vol_count)
                    printf("(none)\n");

                free_instance(&(outInsts[i]));
            }
        }
        /* TODO: fix free(outInsts); */

    /***********************************************************/
    } else if (!strcmp(command, "describeResource")) {
        char *type = NULL;
        ncResource *outRes;

        int rc = ncDescribeResourceStub(stub, &meta, type, &outRes);
        if (rc != 0) {
            printf("ncDescribeResource() failed: error=%d\n", rc);
            exit(1);
        }
        printf("node status=[%s] memory=%d/%d disk=%d/%d cores=%d/%d subnets=[%s]\n",
               outRes->nodeStatus,
               outRes->memorySizeMax, outRes->memorySizeAvailable, outRes->diskSizeMax, outRes->diskSizeAvailable, outRes->numberOfCoresMax,
               outRes->numberOfCoresAvailable, outRes->publicSubnets);

    /***********************************************************/
    } else if (!strcmp(command, "attachVolume")) {
        CHECK_PARAM(instance_id, "instance ID");
        CHECK_PARAM(volume_id, "volume ID");
        CHECK_PARAM(remote_dev, "remote dev");
        CHECK_PARAM(local_dev, "local dev");

        int rc = ncAttachVolumeStub(stub, &meta, instance_id, volume_id, remote_dev, local_dev);
        if (rc != 0) {
            printf("ncAttachVolume() failed: error=%d\n", rc);
            exit(1);
        }

    /***********************************************************/
    } else if (!strcmp(command, "detachVolume")) {
        CHECK_PARAM(instance_id, "instance ID");
        CHECK_PARAM(volume_id, "volume ID");
        CHECK_PARAM(remote_dev, "remote dev");
        CHECK_PARAM(local_dev, "local dev");

        int rc = ncDetachVolumeStub(stub, &meta, instance_id, volume_id, remote_dev, local_dev, force);
        if (rc != 0) {
            printf("ncDetachVolume() failed: error=%d\n", rc);
            exit(1);
        }

    /***********************************************************/
    } else if (!strcmp(command, "describeSensors")) {

        sensorResource **res;
        int resSize;

        int rc = ncDescribeSensorsStub(stub, &meta, 20, 5000, NULL, 0, NULL, 0, &res, &resSize);
        if (rc != 0) {
            printf("ncDescribeSensors() failed: error=%d\n", rc);
            exit(1);
        }
        char buf[102400];
        sensor_res2str(buf, sizeof(buf), res, resSize);
        printf("resources: %d\n%s\n", resSize, buf);

    /***********************************************************/
    } else if (!strcmp(command, "_convertTimestamp")) {
        CHECK_PARAM(timestamp_str, "timestamp");

        axutil_date_time_t *dt = unixms_to_datetime(stub->env, 0123L);
        long long ts_l = datetime_to_unixms(dt, stub->env);
        printf("timestamp: %lld\n", ts_l);

    /***********************************************************/
    } else {
        fprintf(stderr, "ERROR: command %s unknown (try -h)\n", command);
        exit(1);
    }

    if (local) {
        pthread_exit(NULL);
    } else {
        _exit(0);
    }
}
Пример #2
0
int main (int argc, char **argv) 
{
	char * nc_hostport = DEFAULT_NC_HOSTPORT;
    char * walrus_hostport = DEFAULT_WALRUS_HOSTPORT;
    char * instance_id = NULL;
    char * image_id = NULL;
    char * image_manifest = NULL;
    char * kernel_id = NULL;
    char * kernel_manifest = NULL;
    char * ramdisk_id = NULL;
    char * ramdisk_manifest = NULL;
    char * reservation_id = NULL;
    char * mac_addr = strdup (DEFAULT_MAC_ADDR);
    char * volume_id = NULL;
    char * remote_dev = NULL;
    char * local_dev = NULL;
    int force = 0;
    char * user_data = NULL;
    char * launch_index = NULL;
    char ** group_names = NULL;
    int group_names_size = 0;
	char * command = NULL;
    int count = 1;
	int ch;
    
	while ((ch = getopt(argc, argv, "hdn:w:i:m:k:r:e:a:c:h:V:R:L:FU:I:G:")) != -1) {
		switch (ch) {
        case 'c':
            count = atoi (optarg);
            break;
        case 'd':
            debug = 1;
            break;
        case 'n':
            nc_hostport = optarg; 
            break;
        case 'w':
            walrus_hostport = optarg; 
            break;
        case 'i':
            instance_id = optarg; 
            break;
        case 'm':
            image_id = strtok (optarg, ":");
            image_manifest = strtok (NULL, ":");
            if (image_id==NULL || image_manifest==NULL) {
                fprintf (stderr, "ERROR: could not parse image [id:manifest] paramters (try -h)\n");
                exit (1);
            }
            break;
        case 'k':
            kernel_id = strtok (optarg, ":");
            kernel_manifest = strtok (NULL, ":");
            if (kernel_id==NULL || kernel_manifest==NULL) {
                fprintf (stderr, "ERROR: could not parse kernel [id:manifest] paramters (try -h)\n");
                exit (1);
            }
            break;
        case 'r':
            ramdisk_id = strtok (optarg, ":");
            ramdisk_manifest = strtok (NULL, ":");
            if (ramdisk_id==NULL || ramdisk_manifest==NULL) {
                fprintf (stderr, "ERROR: could not parse ramdisk [id:manifest] paramters (try -h)\n");
                exit (1);
            }
            break;
        case 'e':
            reservation_id = optarg;
            break;
        case 'a':
            mac_addr = optarg;
            break;
        case 'V':
            volume_id = optarg;
            break;
        case 'R':
            remote_dev = optarg;
            break;
        case 'L':
            local_dev = optarg;
            break;
        case 'F':
            force = 1;
            break;
        case 'U':
            user_data = optarg;
            break;
        case 'I':
            launch_index = optarg;
            break;
        case 'G':
        {
            int i;
            group_names_size = 1;
            for (i=0; optarg[i]; i++) 
                if (optarg[i]==':')
                    group_names_size++;
            group_names = malloc (sizeof(char *) * group_names_size);
            if (group_names==NULL) {
                fprintf (stderr, "ERROR: out of memory for group_names[]\n");
                exit (1);
            }
            group_names [0] = strtok (optarg, ":");
            for (i=1; i<group_names_size; i++)
                group_names[i] = strtok (NULL, ":");
            break;
        }
        case 'h':
            usage (); // will exit
        case '?':
        default:
            fprintf (stderr, "ERROR: unknown parameter (try -h)\n");
            exit (1);
		}
	}
	argc -= optind;
	argv += optind;
    
	if (argc>0) {
		command = argv[0];
        if (argc>1) {
            fprintf (stderr, "WARNING: too many parameters, using first one as command\n");
        }
	} else {
        fprintf (stderr, "ERROR: command not specified (try -h)\n");
        exit (1);
    }
    
    ncMetadata meta = { "correlate-me-please", "eucalyptus" };
    ncInstParams params = { 64, 64, 1 };
    ncStub * stub;
    char configFile[1024], policyFile[1024];
    char *euca_home;
    int rc, use_wssec;
    char *tmpstr;
    
    euca_home = getenv("EUCALYPTUS");
    if (!euca_home) {
        snprintf(configFile, 1024, "/etc/eucalyptus/eucalyptus.conf");
        snprintf(policyFile, 1024, "/var/lib/eucalyptus/keys/nc-client-policy.xml");
    } else {
        snprintf(configFile, 1024, "%s/etc/eucalyptus/eucalyptus.conf", euca_home);
        snprintf(policyFile, 1024, "%s/var/lib/eucalyptus/keys/nc-client-policy.xml", euca_home);
    }
    rc = get_conf_var(configFile, "ENABLE_WS_SECURITY", &tmpstr);
    if (rc != 1) {
        logprintf("ERROR: parsing config file (%s) for ENABLE_WS_SECURITY\n",configFile);
        exit(1);
    } else {
        if (!strcmp(tmpstr, "Y")) {
            use_wssec = 1;
        } else {
            use_wssec = 0;
        }
    }
    
    char nc_url [BUFSIZE];
    snprintf (nc_url, BUFSIZE, "http://%s%s", nc_hostport, NC_ENDPOINT);
    if (debug) printf ("connecting to NC at %s\n", nc_url);
    stub = ncStubCreate (nc_url, "NCclient.log", NULL);
    if (!stub) {
        fprintf (stderr, "ERROR: failed to connect to Web service\n");
        exit (2);
    }
    
    if (use_wssec) {
        if (debug) printf ("using policy file %s\n", policyFile);
        rc = InitWSSEC(stub->env, stub->stub, policyFile);
        if (rc) {
            fprintf (stderr, "ERROR: cannot initialize WS-SEC policy from %s\n", policyFile);
            exit(1);
        } 
    }
    
    char * image_url = NULL;
    if (image_manifest) {
        char t [BUFSIZE];
        snprintf (t, BUFSIZE, "http://%s%s/%s", walrus_hostport, WALRUS_ENDPOINT, image_manifest);
        image_url = strdup (t);
    }

    char * kernel_url = NULL;
    if (kernel_manifest) {
        char t [BUFSIZE];
        snprintf (t, BUFSIZE, "http://%s%s/%s", walrus_hostport, WALRUS_ENDPOINT, kernel_manifest);
        kernel_url = strdup (t);
    }

    char * ramdisk_url = NULL;
    if (ramdisk_manifest) {
        char t [BUFSIZE];
        snprintf (t, BUFSIZE, "http://%s%s/%s", walrus_hostport, WALRUS_ENDPOINT, ramdisk_manifest);
        ramdisk_url = strdup (t);
    }

    /***********************************************************/
    if (!strcmp (command, "runInstance")) {
        CHECK_PARAM(image_id, "image ID and manifest path");
        CHECK_PARAM(kernel_id, "kernel ID and manifest path");

        char *privMac, *pubMac;
        int vlan = 3;
        privMac = strdup (mac_addr);
        mac_addr [0] = 'b';
        mac_addr [1] = 'b';
        pubMac = strdup (mac_addr);

        /* generate random IDs if they weren't specified*/
#define C rand()%26 + 97

        while (count--) {
            char * iid, * rid;

            char ibuf [8];
            if (instance_id==NULL || count>1) {
                snprintf (ibuf, 8, "i-%c%c%c%c%c", C, C, C, C, C);
                iid = ibuf;
            } else {
                iid = instance_id;
            }

            char rbuf [8];
            if (reservation_id==NULL || count>1) {
                snprintf (rbuf, 8, "r-%c%c%c%c%c", C, C, C, C, C);
                rid = rbuf;
            } else {
                rid = reservation_id;
            }
            
            ncInstance * outInst;
            int rc = ncRunInstanceStub(stub, &meta, 
                                       iid, rid,
                                       &params, 
                                       image_id, image_url, 
                                       kernel_id, kernel_url, 
                                       ramdisk_id, ramdisk_url, 
                                       "", /* key */
                                       privMac, pubMac, vlan, 
                                       user_data, launch_index, group_names, group_names_size, /* CC stuff */
                                       &outInst);
            if (rc != 0) {
                printf("ncRunInstance() failed: instanceId=%s error=%d\n", instance_id, rc);
                exit(1);
            }
            printf("instanceId=%s stateCode=%d stateName=%s\n", outInst->instanceId, outInst->stateCode, outInst->stateName);
            free_instance(&outInst);
        }
    
        /***********************************************************/
    } else if (!strcmp(command, "terminateInstance")) {
        CHECK_PARAM(instance_id, "instance ID");
        
        int shutdownState, previousState;
        int rc = ncTerminateInstanceStub (stub, &meta, instance_id, &shutdownState, &previousState);
        if (rc != 0) {
            printf("ncTerminateInstance() failed: error=%d\n", rc);
            exit(1);
        }
        printf("shutdownState=%d, previousState=%d\n", shutdownState, previousState);

        /***********************************************************/
    } else if (!strcmp(command, "describeInstances")) {
        /* TODO: pull out of argv[] requested instanceIDs */
        ncInstance ** outInsts;
        int outInstsLen, i;
        int rc = ncDescribeInstancesStub(stub, &meta, NULL, 0, &outInsts, &outInstsLen);
        if (rc != 0) {
            printf("ncDescribeInstances() failed: error=%d\n", rc);
            exit(1);
        }
        for (i=0; i<outInstsLen; i++) {
            ncInstance * inst = outInsts[i];
            printf("instanceId=%s state=%s time=%d\n", inst->instanceId, inst->stateName, inst->launchTime);
            if (debug) {
                printf ("              userData=%s launchIndex=%s groupNames=", inst->userData, inst->launchIndex);
                if (inst->groupNamesSize>0) {
                    int j;
                    for (j=0; j<inst->groupNamesSize; j++) {
                        if (j>0) 
                            printf (":");
                        printf ("%s", inst->groupNames[j]);
                    }
                } else {
                    printf ("(none)");
                }
                printf ("\n");
                
                printf ("              attached volumes: ");
                if (inst->volumesSize>0) {
                    int j;
                    for (j=0; j<inst->volumesSize; j++) {
                        if (j>0)
                            printf ("                                ");
                        printf ("%s %s %s\n", inst->volumes[j].volumeId, inst->volumes[j].remoteDev, inst->volumes[j].localDev);
                    }
                } else {
                    printf ("(none)\n");
                }

                free_instance(&(outInsts[i]));
            }
        }
        /* TODO: fix free(outInsts); */

    /***********************************************************/
    } else if (!strcmp(command, "describeResource")) {
        char * type = NULL;
        ncResource *outRes;
        
        int rc = ncDescribeResourceStub(stub, &meta, type, &outRes);
        if (rc != 0) {
            printf("ncDescribeResource() failed: error=%d\n", rc);
            exit(1);
        }
        printf ("node status=[%s] memory=%d/%d disk=%d/%d cores=%d/%d subnets=[%s]\n", 
                outRes->nodeStatus, 
                outRes->memorySizeMax, outRes->memorySizeAvailable,
                outRes->diskSizeMax, outRes->diskSizeAvailable,
                outRes->numberOfCoresMax, outRes->numberOfCoresAvailable,
                outRes->publicSubnets);

    /***********************************************************/
    } else if (!strcmp(command, "attachVolume")) {
        CHECK_PARAM(instance_id, "instance ID");
        CHECK_PARAM(volume_id, "volume ID");
        CHECK_PARAM(remote_dev, "remote dev");
        CHECK_PARAM(local_dev, "local dev");
        
        int rc = ncAttachVolumeStub (stub, &meta, instance_id, volume_id, remote_dev, local_dev);
        if (rc != 0) {
            printf("ncAttachVolume() failed: error=%d\n", rc);
            exit(1);
        }

    /***********************************************************/
    } else if (!strcmp(command, "detachVolume")) {
        CHECK_PARAM(instance_id, "instance ID");
        CHECK_PARAM(volume_id, "volume ID");
        CHECK_PARAM(remote_dev, "remote dev");
        CHECK_PARAM(local_dev, "local dev");
        
        int rc = ncDetachVolumeStub (stub, &meta, instance_id, volume_id, remote_dev, local_dev, force);
        if (rc != 0) {
            printf("ncDetachVolume() failed: error=%d\n", rc);
            exit(1);
        }
        
    /***********************************************************/
    } else {
        fprintf (stderr, "ERROR: command %s unknown (try -h)\n", command);
        exit (1);
    }
    
    exit(0);
}