diff --git a/src/server/simpleslave.c b/src/server/simpleslave.c new file mode 100644 --- /dev/null +++ b/src/server/simpleslave.c @@ -0,0 +1,190 @@ +/* + Copyright 2009 Nathan Phillip Brink, Ethan Zonca, Matthew Orlando + + This file is a part of DistRen. + + DistRen is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DistRen is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with DistRen. If not, see . + +*/ + +#include "slavefuncs.h" + +#include "common/asprintf.h" +#include "common/options.h" + +#include +#include +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + + char *datadir; + char *server; + char *username; + char *password; // @TODO: Binki: fill me with confiness + char *hostname; + cfg_opt_t myopts[] = { + CFG_SIMPLE_STR("username", &username), + CFG_SIMPLE_STR("datadir", &datadir), + CFG_SIMPLE_STR("server", &server), + CFG_SIMPLE_STR("hostname", &hostname), + CFG_END() + }; + cfg_t * my_cfg; + + struct options_common *commonopts; + + // struct distrenjob *myjob; /* Structure to hold data gathered from the XML file */ + + // struct remoteio *comm_slave; + + /** + initializations + */ + datadir = NULL; + server = NULL; + username = NULL; + + char curopt; + + while(((char)-1) != (curopt = getopt(argc, argv, "u:th"))) + { + if(curopt == ':') + { + fprintf(stderr, "-%c: is missing an argument\n", optopt); + return 1; + } + else if(curopt == '?') + { + fprintf(stderr, "-%c: invalid option specified\n", optopt); + return 1; + } + else if(curopt == 'h') + { + fprintf(stderr, "Usage: distrenslave [option] \nStarts a distren slave\n\t-u\tset username (run after fresh install)\n\t-t\tEnter test mode\n\t-h\tshow this help\n"); + return 2; + } + else if(curopt == 't') + { + slaveTest(); + return 0; + } + else if(curopt == 'u') + username = strdup(optarg); + fprintf(stderr, "Putting username \"%s\" in distrenslave.conf\n", username); + conf_replace("distrenslave.conf", "!username", username); + fprintf(stderr, "Please invoke distrenslave with no arguments to run with the username you just set\n"); + return 0; + } + + /* Get conf data */ + options_init(argc, argv, &my_cfg, myopts, "slave", &commonopts); + + + /* Notifies the user if there no username in .conf */ + if(checkUsername(username)) + return 1; + + /* + fprintf(stderr, "Connecting to server...\n"); + if(remoteio_open(&comm_slave, commonopts->remoteio, server)) + { + fprintf(stderr, "Error connecting to server; exiting\n"); + return 1; + } +*/ + + // Variables needed for main loop + int jobnum = 0; + int framenum = 0; + int slavekey = atoi(username); // @TODO: Make this more friendly + + char *urltoTar; /* Full URL to the server-side location of job#.tgz */ + char *pathtoTar; /* Full path to the location of the job#.tgz */ + + char *urltoOutput; /* Full URL where output is posted */ + char *pathtoOutput; /* Full path to the output (rendered) file */ + + char *pathtoJobfile; /* Full path to the job's main file */ + char *outputExt = "jpg"; /* Output Extension (e.g., JPG) */ + + int haveWork = 0; + int quit = 0; + + // Main loop + while(!quit) + { + + // request work + fprintf(stderr,"Requesting work...\n"); + haveWork = _web_getwork(slavekey, password, &jobnum, &framenum); + + /* If we got a frame */ + if(haveWork) + { + fprintf(stderr,"Got work from server...\n"); + /* @TODO: Add remotio hooks */ + // jobnum = remoteio_read(jobnum); /* Set jobnum from remoteio (we could use info from struct, but we need this info to download the xmlfile */ + // framenum = remoteio_read(jobnum); /* Set framenum from remoteio */ + // outputExt = remotio)read(outputExt); /* Set output extension from remotio */ + + fprintf(stderr, "Preparing to render frame %d in job %d\n", framenum, jobnum); + + prepareJobPaths(jobnum, framenum, outputExt, datadir, &urltoTar, &pathtoTar, &pathtoJobfile, &urltoOutput, &pathtoOutput); + free(outputExt); + + if(downloadTar(urltoTar, pathtoTar)) + return 1; + + unpackJob(pathtoTar, jobnum); + + /* Execute blender */ + if(exec_blender(pathtoJobfile, pathtoOutput, framenum)) + { + fprintf(stderr,"Error running Blender. Check your installation and/or your PATH.\n"); + return 1; + } + free(pathtoJobfile); + + /* Post-execution */ + fprintf(stderr, "Finished frame %d in job %d, uploading...\n", framenum, jobnum); + uploadOutput(pathtoOutput, urltoOutput, jobnum, framenum, slavekey); // @TODO: Handle return value + + free(urltoOutput); + free(pathtoOutput); + + // Tell the server that rendering and upload are complete + _web_finishframe(slavekey, password, jobnum, framenum); + } + else + fprintf(stderr,"Nothing to do. Idling...\n"); + + // @TODO: If the server says that every frame for the last jobnum is finished, OR if the data is getting old + if(1 == 0) + { + // Note: individual frames are already deleted after uploading, + // except for ones that couldn't be uploaded + delete_jobdata(jobnum, datadir); + } + + sleep(5); // Poll 5 seconds. @TODO: Remove all polling + } + + fprintf(stderr,"Goodbye!\n"); + return 0; +}