summaryrefslogblamecommitdiffstats
path: root/src/client/main.cpp
blob: 10a497b1d93fb4005473e0b966d91981aa086708 (plain) (tree)

























































































































                                                                               
                                                     















                                                                        
/*
 # Copyright (c) 2011 - OpenSLX Project, Computer Center University of Freiburg
 #
 # This program is free software distributed under the GPL version 2.
 # See http://gpl.openslx.org/
 #
 # If you have any feedback please consult http://feedback.openslx.org/ and
 # send your suggestions, praise, or complaints to feedback@openslx.org
 #
 # General information about OpenSLX can be found at http://openslx.org/
 */

#include <sstream>
#include <iostream>
#include <stdio.h>
#include <libgearman/gearman.h>

#include "../version.h"

using namespace std;

static void usage(char *name)
{
    printf("usage: %s -h <host> [-p <port>] -i <image> -d <device>\n", name);
    printf("\t-h <host>\t gearman job server host\n");
    printf("\t-p <port>\t gearman job server port\n");
    printf("\t-i <image>\t remote image file to load\n");
    printf("\t-d <device>\t local nbd-device to use\n");
    printf("\t-v\t\t print version and exit\n");
}

int main(int argc, char* argv[])
{
    string host("");
    in_port_t port = 0;
    string image("");
    string device("");

    gearman_return_t ret;
    gearman_client_st client;

    // parse command line arguments
    int c;
    while ((c = getopt(argc, argv, "h:p:i:d:v")) != -1)
    {
        switch (c)
        {
        case 'h':
            host = optarg;
            break;
        case 'p':
            port = (in_port_t) atoi(optarg);
            break;
        case 'i':
            image = optarg;
            break;
        case 'd':
            device = optarg;
            break;
        case 'v':
            printf("Version: %s\n", VERSION_STRING);
            exit(0);
        default:
            usage(argv[0]);
            exit(1);
        }
    }

    if (host == "" || image == "" || device == "")
    {
        usage(argv[0]);
        exit(1);
    }

    // initialize gearman client
    if (gearman_client_create(&client) == NULL)
    {
        cerr << "[ERROR] Memory allocation failure on client creation" << endl;
        exit(1);
    }
    ret = gearman_client_add_server(&client, host.c_str(), port);
    if (ret != GEARMAN_SUCCESS)
    {
        cerr << "[ERROR] " << gearman_client_error(&client) << endl;
        exit(1);
    }

    // main loop
    char *result;
    size_t result_size;
    string msg;
    while (1)
    {
        // send request to gearman job server
        result = (char *) gearman_client_do(&client, "start_nbd_server", NULL,
                (void*) image.c_str(), (size_t) image.length(), &result_size,
                &ret);

        if (ret == GEARMAN_WORK_DATA)
        {
            msg = result;
            free(result);
            continue;
        }
        else if (ret == GEARMAN_WORK_STATUS)
        {
            uint32_t m, n;
            gearman_client_do_status(&client, &n, &m);
            printf("[INFO] Status: %u/%u\n", n, m);
            continue;
        }
        else if (ret == GEARMAN_SUCCESS)
        {
            // start nbd-client
            stringstream command;
            command << "nbd-client " << host << " " << msg << " " << device;
            cout << "[DEBUG] " << "Running command: " << command.str() << endl;
            system(command.str().c_str());
            free(result);
        }
        else if (ret == GEARMAN_WORK_FAIL)
        {
            cerr << "[REMOTE ERROR] " << msg << endl;
            cerr << "[ERROR] Work failed" << endl;
            free(result);
        }
        else
        {
            cerr << "[ERROR] " << gearman_client_error(&client) << endl;
            free(result);
        }

        break;
    }

    // cleanup
    gearman_client_free(&client);
    return 0;
}