fixup! refactor: move executor function into it's own file
This commit is contained in:
parent
05701d9d85
commit
0f1aa982f4
1
Makefile
1
Makefile
@ -30,6 +30,7 @@ out/obj/%.o: src/%.c | $(OBJDIR)
|
|||||||
$(CC) -c $? $(CFLAGS) -o $@
|
$(CC) -c $? $(CFLAGS) -o $@
|
||||||
|
|
||||||
OBJ += out/obj/cli.o
|
OBJ += out/obj/cli.o
|
||||||
|
OBJ += out/obj/executor.o
|
||||||
OBJ += out/obj/log.o
|
OBJ += out/obj/log.o
|
||||||
OBJ += out/obj/main.o
|
OBJ += out/obj/main.o
|
||||||
OBJ += out/obj/notify.o
|
OBJ += out/obj/notify.o
|
||||||
|
7
include/executor.h
Normal file
7
include/executor.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef SCI_EXECUTOR_H
|
||||||
|
#define SCI_EXECUTOR_H
|
||||||
|
|
||||||
|
void executor(void* pipeline_event);
|
||||||
|
void set_logdir(const char* logdir);
|
||||||
|
|
||||||
|
#endif
|
@ -16,7 +16,6 @@
|
|||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
#include "log.h"
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
102
src/executor.c
Normal file
102
src/executor.c
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#include "executor.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "optional.h"
|
||||||
|
#include "pipeline.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <linux/limits.h>
|
||||||
|
#include <spawn.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <uuid/uuid.h>
|
||||||
|
|
||||||
|
const char* log_dir = "./"; // NOTE: must end with a /
|
||||||
|
|
||||||
|
void set_logdir(const char* logdir) {
|
||||||
|
log_dir = logdir;
|
||||||
|
struct stat st = {0};
|
||||||
|
if(stat(log_dir, &st) == -1)
|
||||||
|
mkdir(log_dir, 0700);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* create_pipeline_id() {
|
||||||
|
uuid_t uuid;
|
||||||
|
uuid_generate(uuid);
|
||||||
|
char* pipeline_id = malloc(32);
|
||||||
|
uuid_unparse_lower(uuid, pipeline_id);
|
||||||
|
return pipeline_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional_int open_logfile(const char* const pipeline_id) {
|
||||||
|
optional_int result;
|
||||||
|
result.has_value = false;
|
||||||
|
result.value = 0;
|
||||||
|
char* log_file = join(pipeline_id, ".log");
|
||||||
|
char* log_filepath = join(log_dir, log_file);
|
||||||
|
int fd = open(log_filepath, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||||
|
if (fd != -1) {
|
||||||
|
result.has_value = true;
|
||||||
|
result.value = fd;
|
||||||
|
} else
|
||||||
|
perror("open");
|
||||||
|
free(log_file);
|
||||||
|
free(log_filepath);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void executor(void* data) {
|
||||||
|
// Create pipeline id
|
||||||
|
char* pipeline_id = create_pipeline_id();
|
||||||
|
|
||||||
|
// Create logfile path
|
||||||
|
optional_int fd = open_logfile(pipeline_id);
|
||||||
|
if(!fd.has_value) {
|
||||||
|
log_error("could not open log file - not starting pipeline");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// spawn the process
|
||||||
|
pid_t pid;
|
||||||
|
posix_spawn_file_actions_t actions;
|
||||||
|
posix_spawn_file_actions_init(&actions);
|
||||||
|
posix_spawn_file_actions_adddup2(&actions, fd.value, STDOUT_FILENO);
|
||||||
|
posix_spawn_file_actions_adddup2(&actions, fd.value, STDERR_FILENO);
|
||||||
|
const pipeline_event* const e = data;
|
||||||
|
char* path = join("PATH=", getenv("PATH"));
|
||||||
|
char* name = join("SCI_PIPELINE_NAME=", e->name);
|
||||||
|
char* url = join("SCI_PIPELINE_URL=", e->url);
|
||||||
|
char* trigger = join("SCI_PIPELINE_TRIGGER=", e->trigger);
|
||||||
|
char* id = join("SCI_PIPELINE_ID=", pipeline_id);
|
||||||
|
char* envp[] = { path, name, url, trigger, id, NULL };
|
||||||
|
int argc;
|
||||||
|
char** argv = argv_split(e->command, &argc);
|
||||||
|
log_trace("executing pipeline %s with argv:", e->name);
|
||||||
|
for(int i = 0; i < argc; i++)
|
||||||
|
log_trace(" \"%s\"", argv[i]);
|
||||||
|
char arg0[PATH_MAX];
|
||||||
|
if(which(argv[0], arg0, PATH_MAX) == -1)
|
||||||
|
goto end;
|
||||||
|
if(posix_spawn(&pid, arg0, &actions, NULL, argv, envp) != 0) {
|
||||||
|
perror("posix_spawn");
|
||||||
|
goto end; // I know. The raptors have picked up the scent. I'll just have to mask it with more stinky code.
|
||||||
|
}
|
||||||
|
log_info("{%s} (%s) spawned", pipeline_id, e->name);
|
||||||
|
|
||||||
|
// Wait for process to complete
|
||||||
|
int status;
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
log_info("{%s} (%s) exited with status %d", pipeline_id, e->name, status);
|
||||||
|
char buf[32];
|
||||||
|
sprintf(buf, "exited with status %d", status);
|
||||||
|
write(fd.value, buf, strnlen(buf, 32));
|
||||||
|
end:
|
||||||
|
argv_free(argv);
|
||||||
|
close(fd.value);
|
||||||
|
free(pipeline_id);
|
||||||
|
free(name);
|
||||||
|
free(url);
|
||||||
|
free(trigger);
|
||||||
|
free(id);
|
||||||
|
}
|
94
src/main.c
94
src/main.c
@ -16,102 +16,17 @@
|
|||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
|
#include "executor.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "notify.h"
|
#include "notify.h"
|
||||||
#include "pipeline.h"
|
#include "pipeline.h"
|
||||||
#include "threadpool.h"
|
#include "threadpool.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include <fcntl.h>
|
#include <stdlib.h>
|
||||||
#include <linux/limits.h>
|
|
||||||
#include <spawn.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <uuid/uuid.h>
|
|
||||||
#include <wait.h>
|
|
||||||
|
|
||||||
threadpool* pool = NULL;
|
threadpool* pool = NULL;
|
||||||
char* log_dir = "./"; // NOTE: must end with a /
|
|
||||||
|
|
||||||
char* create_pipeline_id() {
|
|
||||||
uuid_t uuid;
|
|
||||||
uuid_generate(uuid);
|
|
||||||
char* pipeline_id = malloc(32);
|
|
||||||
uuid_unparse_lower(uuid, pipeline_id);
|
|
||||||
return pipeline_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
optional_int open_logfile(const char* const pipeline_id) {
|
|
||||||
optional_int result;
|
|
||||||
result.has_value = false;
|
|
||||||
result.value = 0;
|
|
||||||
char* log_file = join(pipeline_id, ".log");
|
|
||||||
char* log_filepath = join(log_dir, log_file);
|
|
||||||
int fd = open(log_filepath, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
|
||||||
if (fd != -1) {
|
|
||||||
result.has_value = true;
|
|
||||||
result.value = fd;
|
|
||||||
} else
|
|
||||||
perror("open");
|
|
||||||
free(log_file);
|
|
||||||
free(log_filepath);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void executor(void* data) {
|
|
||||||
// Create pipeline id
|
|
||||||
char* pipeline_id = create_pipeline_id();
|
|
||||||
|
|
||||||
// Create logfile path
|
|
||||||
optional_int fd = open_logfile(pipeline_id);
|
|
||||||
if(!fd.has_value) {
|
|
||||||
log_error("could not open log file - not starting pipeline");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// spawn the process
|
|
||||||
pid_t pid;
|
|
||||||
posix_spawn_file_actions_t actions;
|
|
||||||
posix_spawn_file_actions_init(&actions);
|
|
||||||
posix_spawn_file_actions_adddup2(&actions, fd.value, STDOUT_FILENO);
|
|
||||||
posix_spawn_file_actions_adddup2(&actions, fd.value, STDERR_FILENO);
|
|
||||||
const pipeline_event* const e = data;
|
|
||||||
char* path = join("PATH=", getenv("PATH"));
|
|
||||||
char* name = join("SCI_PIPELINE_NAME=", e->name);
|
|
||||||
char* url = join("SCI_PIPELINE_URL=", e->url);
|
|
||||||
char* trigger = join("SCI_PIPELINE_TRIGGER=", e->trigger);
|
|
||||||
char* id = join("SCI_PIPELINE_ID=", pipeline_id);
|
|
||||||
char* envp[] = { path, name, url, trigger, id, NULL };
|
|
||||||
int argc;
|
|
||||||
char** argv = argv_split(e->command, &argc);
|
|
||||||
log_trace("executing pipeline %s with argv:", e->name);
|
|
||||||
for(int i = 0; i < argc; i++)
|
|
||||||
log_trace(" \"%s\"", argv[i]);
|
|
||||||
char arg0[PATH_MAX];
|
|
||||||
if(which(argv[0], arg0, PATH_MAX) == -1)
|
|
||||||
goto end;
|
|
||||||
if(posix_spawn(&pid, arg0, &actions, NULL, argv, envp) != 0) {
|
|
||||||
perror("posix_spawn");
|
|
||||||
goto end; // I know. The raptors have picked up the scent. I'll just have to mask it with more stinky code.
|
|
||||||
}
|
|
||||||
log_info("{%s} (%s) spawned", pipeline_id, e->name);
|
|
||||||
|
|
||||||
// Wait for process to complete
|
|
||||||
int status;
|
|
||||||
waitpid(pid, &status, 0);
|
|
||||||
log_info("{%s} (%s) exited with status %d", pipeline_id, e->name, status);
|
|
||||||
char buf[32];
|
|
||||||
sprintf(buf, "exited with status %d", status);
|
|
||||||
write(fd.value, buf, strnlen(buf, 32));
|
|
||||||
end:
|
|
||||||
argv_free(argv);
|
|
||||||
close(fd.value);
|
|
||||||
free(pipeline_id);
|
|
||||||
free(name);
|
|
||||||
free(url);
|
|
||||||
free(trigger);
|
|
||||||
free(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_event(pipeline_event* const e) {
|
void on_event(pipeline_event* const e) {
|
||||||
if(!threadpool_add_work(pool, executor, (void*)e))
|
if(!threadpool_add_work(pool, executor, (void*)e))
|
||||||
@ -185,12 +100,9 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(args.pipeline_log_dir.has_value)
|
if(args.pipeline_log_dir.has_value)
|
||||||
log_dir = args.pipeline_log_dir.value;
|
set_logdir(args.pipeline_log_dir.value);
|
||||||
|
|
||||||
struct stat st = {0};
|
struct stat st = {0};
|
||||||
if(stat(log_dir, &st) == -1)
|
|
||||||
mkdir(log_dir, 0700);
|
|
||||||
|
|
||||||
if(stat("/tmp/sci", &st) == -1)
|
if(stat("/tmp/sci", &st) == -1)
|
||||||
mkdir("/tmp/sci", 0700);
|
mkdir("/tmp/sci", 0700);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user