diff --git a/src/server/slave.c b/src/server/slave.c new file mode 100644 --- /dev/null +++ b/src/server/slave.c @@ -0,0 +1,142 @@ +/* + * ********************************************************************************** + * Slave functions / etc resides below. Wouldn't a seperate file make this easier?? + * + * Slave listens on server for a command in the format of each function... + * We need if's for returns... ==> watchdog + * ********************************************************************************** +*/ + + +///////////////////// Semi-pseudo Slave Code /////////////////////////// + +int slavestatus = 0; + +if(no username in config file, no key present){ + fprintf(stderr "run distrend -c username] [emailaddr] to register") +} +if(they use a -c flag according to getopt, with 2 args){ + register_user(username, email); which returns a uniquely random url to a key + get(uniquely-random-url-to-key); + fprintf(stderr, "you registered, hopefully successfully. Invoke distrend with no args now."); +} +if(username is in conf file and key is present){ + loginuser(username); +} + +if(slave recieves "start frame#, job#"){ + get(http://distren.protofusion.org/srv/job#.tgz); + tar -xvf job#.tgz /tmp/distren/job#; somehow + exec_blender(job#.blend, job#.frame#.JPG, job#); (check the args, we'll need to adjust for different output formats)... set SLAVESTATUS=1 while rendering, SLAVESTATUS=2 when done +} +if(SLAVESTATUS==2){ + tell the server "done with frame# in job#"; + SLAVESTATUS=0 +} +if(SLAVESTATUS==0){ + tell the server "i ain't got no frames to render"; +} +while(SLAVESTATUS==1){ + tell the server "rendering this friggn frame"; + delay(1000); +} + + + + + + + + + + + + +// Registration on server. Needs attention. Prevent account spamming. +// Key transfer? +// Set up something like: distrend -c username email@example.com +void registeruser(char *username, char *email){ + // Logs into sandboxed user on zserver2 and registers a user. Should eventually generate a key on the server and return it to the user. + // All created user accounts should be sandboxed accordingly, requiring a different skel, and the default shell to be rbash. Also, + // a custom path defined in the .bash_profile of the skel is needed. + char buf[10]; + struct execio *testrem; + char *execargv[] = + { + "ssh", + "distren_setup@protofusion.org", + "-i", + "setup.rsa", // default distributed key, account can only create users. + "-p", + "23", + "sudo /usr/sbin/useradd", + "-M", + "-c", + email, + "-d", + "/home/distren", + "--gid", + "541", // Add in shellscript to generate ssh key and return it to the user somehow + username, + (char *)NULL + }; + size_t readlen; + fprintf(stderr, "Opening stream:\n", execio_open(&testrem, "ssh", execargv)); + buf[9] = '\0'; // null-terminating the array... + while(!execio_read(testrem, buf, 9, &readlen)) // What's with the readlen stuff? + { + if(readlen > 9) { + fprintf(stderr, "!!!! Something is terribly wrong!\n"); + } + buf[readlen] = '\0'; // Null-terminating the end of it again based on how large the data is? + fprintf(stderr, "read \"%s\"\n", buf); + } + execio_close(testrem); +} + + +void loginuser(char *username){ + // Logs into sandboxed user on zserver2 as a client, currently does nothing + char buf[10]; + struct execio *testrem; + char *execargv[] = + { + "ssh", + "username@protofusion.org", // username must be read from the conf + "-i", + "username.rsa", // Key created from registeruser() + "-p", + "23", + "echo", + "hello", // This should eventually open a non-terminating connection to the server for communication + (char *)NULL + }; + size_t readlen; + fprintf(stderr, "Opening stream:\n", execio_open(&testrem, "ssh", execargv)); + buf[9] = '\0'; // null-terminating the array... + while(!execio_read(testrem, buf, 9, &readlen)) // What's with the readlen stuff? + { + if(readlen > 9) { + fprintf(stderr, "!!!! Something is terribly wrong!\n"); + } + buf[readlen] = '\0'; // Null-terminating the end of it again based on how large the data is? + fprintf(stderr, "read \"%s\"\n", buf); + } + execio_close(testrem); +} + + +// Executors + +/* + It seems that the client will need to know the job number. Is finish_frame going to be on the client or the server? we gotta figure that out! +*/ +void exec_blender(struct blendjob* blendjob, char *input, char *output, int frame) +{ + char *frame_str; + asprintf(frame,frame_str); // GNU/*nix compatible only, fix before releasing win32, although dll for windows for asprintf exists! + int ret; + char *cmd[] = { "blender", "-b", "-o", output, input, "-f", frame_str, (char *)0 }; + ret = execv("/usr/bin/blender", cmd); + finish_frame(blendjob, frame); +}