From 8dc3c7b7693569ac83857e6fe5cdd9b09ebda7bd Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Fri, 10 Apr 2015 07:31:21 +0200 Subject: supporting variables in worker command now --- examples/build_gold_image/biruda.conf | 4 -- src/worker.c | 95 +++++++++++++++++++++++++++++++++-- 2 files changed, 92 insertions(+), 7 deletions(-) diff --git a/examples/build_gold_image/biruda.conf b/examples/build_gold_image/biruda.conf index 4b68f1a..ae21ef8 100644 --- a/examples/build_gold_image/biruda.conf +++ b/examples/build_gold_image/biruda.conf @@ -24,8 +24,6 @@ worker example_build_gold execution = direct command = "/bin/sh ./build_centos6.sh ${ARCH}" -# command = "/bin/sh ./build_centos6.sh x86_64" -# command = "/bin/sh ./build_centos6.sh i686" } worker example_run @@ -37,8 +35,6 @@ worker example_run execution = direct command = "/bin/chroot rhel6-${ARCH} /bin/bash -c '/bin/cat /etc/redhat-release'" -# command = "/bin/chroot rhel6-x64 /bin/bash -c '/bin/cat /etc/redhat-release'" -# command = "/bin/chroot rhel6-i686 /bin/bash -c '/bin/cat /etc/redhat-release'" } webserver diff --git a/src/worker.c b/src/worker.c index 287371a..7807697 100644 --- a/src/worker.c +++ b/src/worker.c @@ -18,6 +18,8 @@ #include "json-c/json.h" +#include "system.h" + const char *worker_exection_mode_str( worker_execution_mode_t mode ) { switch( mode ) { @@ -255,18 +257,103 @@ static gboolean watch_output( GIOChannel *channel, GIOCondition condition, gpoin return TRUE; } +static char *expand_system_variables( const char *s ) +{ + char *r = (char *)malloc( strlen( s ) * 2 ); + char *d = r; + bool var_begin = false; + bool in_var = false; + const char *var = NULL; + const char *p = s; + + while( *p != '\0' && d - r < strlen( s ) * 2 - 1 ) { + switch( *p ) { + case '$': + var_begin = true; + break; + + case '{': + if( var_begin ) { + in_var = true; + var = p + 1; + } else { + fprintf( stderr, "ERROR: Unexpected '{' at position %d in '%s'\n", p-s, s ); + free( r ); + return NULL; + } + break; + + case '}': + if( var_begin ) { + fprintf( stderr, "ERROR: Empty variable declaration '${}' at position %d in '%s'\n", p-s, s ); + free( r ); + return NULL; + } + in_var = false; + var_begin = false; + if( strncmp( var, "ARCH", 4 ) == 0 ) { + char machine_arch[100]; + system_arch( machine_arch, sizeof( machine_arch ) ); + strncpy( d, machine_arch, strlen( machine_arch ) ); + d += strlen( machine_arch ); + } else if( strncmp( var, "OS", 2 ) == 0 ) { + char os_name[100]; + system_os( os_name, sizeof( os_name ) ); + strncpy( d, os_name, strlen( os_name ) ); + d += strlen( os_name ); + } else if( strncmp( var, "HOST", 4 ) == 0 ) { + char hostname[100]; + gethostname( hostname, sizeof( hostname ) ); + strncpy( d, hostname, strlen( hostname ) ); + d += strlen( hostname ); + } else if( strncmp( var, "CPUS", 4 ) == 0 ) { + unsigned int nofCpus = system_available_cpus( ); + char buf[10]; + snprintf( buf, sizeof( buf ), "%d", nofCpus ); + strncpy( d, buf, strlen( buf ) ); + d += strlen( buf ); + } else { + fprintf( stderr, "ERROR: Unknown variable '${%*s}' at position %d in '%s'\n", p-var, var, p-s, s ); + free( r ); + return NULL; + } + break; + + default: + if( in_var ) { + var_begin = false; + } else { + *d = *p; + d++; + } + } + p++; + } + *d = '\0'; + + return r; +} + static void *worker_func( void *thread_data ) { direct_glib_execution_worker_data_t *wed = (direct_glib_execution_worker_data_t *)thread_data; worker_t *worker = wed->worker; + + char *command = expand_system_variables( worker->command ); + if( command == NULL ) { + fprintf( stderr, "ERROR: Failed to substitute variables in command of worker '%s', '%s'\n", + worker->name, command ); + return NULL; + } gchar **args; gint nof_args; GError *error = NULL; - if( !g_shell_parse_argv( worker->command, &nof_args, &args, &error ) ) { + if( !g_shell_parse_argv( command, &nof_args, &args, &error ) ) { fprintf( stderr, "ERROR: Failed to parse command of worker '%s', '%s': %s\n", - worker->name, worker->command, error->message ); + worker->name, command, error->message ); g_strfreev( args ); + free( command ); return NULL; } @@ -283,11 +370,12 @@ static void *worker_func( void *thread_data ) if( !ret ) { fprintf( stderr, "ERROR: Starting worker failed: %s\n", error->message ); g_strfreev( args ); + free( command ); return NULL; } printf( "Worker child with PID " PRIgid " created: %s.\n", - wed->pid, worker->command ); + wed->pid, command ); char *msg = create_worker_created_answer( worker->name, wed->pid ); worker_send_message( worker, msg ); @@ -327,6 +415,7 @@ static void *worker_func( void *thread_data ) worker->execution_data = NULL; g_strfreev( args ); + free( command ); return NULL; } -- cgit v1.2.3-54-g00ecf