int create_log_dirs(const char *app_id, char * const * log_dirs) { char* const* log_root; char *any_one_app_log_dir = NULL; for(log_root=log_dirs; *log_root != NULL; ++log_root) { char *app_log_dir = get_app_log_directory(*log_root, app_id); if (app_log_dir == NULL) { // try the next one } else if (create_directory_for_user(app_log_dir) != 0) { free(app_log_dir); return -1; } else if (any_one_app_log_dir == NULL) { any_one_app_log_dir = app_log_dir; } else { free(app_log_dir); } } if (any_one_app_log_dir == NULL) { fprintf(LOGFILE, "Did not create any app-log directories\n"); return -1; } free(any_one_app_log_dir); return 0; }
void test_get_app_log_dir() { char *expected = TEST_ROOT "/logs/userlogs/app_200906101234_0001"; char *logdir = get_app_log_directory(TEST_ROOT "/logs/userlogs","app_200906101234_0001"); if (strcmp(logdir, expected) != 0) { printf("Fail get_app_log_dir got %s expected %s\n", logdir, expected); exit(1); } free(logdir); }
/** * Function to prepare the application directories for the container. */ int initialize_app(const char *user, const char *app_id, const char* nmPrivate_credentials_file, char* const* local_dirs, char* const* log_roots, char* const* args) { if (app_id == NULL || user == NULL) { fprintf(LOGFILE, "Either app_id is null or the user passed is null.\n"); return INVALID_ARGUMENT_NUMBER; } // create the user directory on all disks int result = initialize_user(user, local_dirs); if (result != 0) { return result; } ////////////// create the log directories for the app on all disks char* const* log_root; char *any_one_app_log_dir = NULL; for(log_root=log_roots; *log_root != NULL; ++log_root) { char *app_log_dir = get_app_log_directory(*log_root, app_id); if (app_log_dir == NULL) { // try the next one } else if (create_directory_for_user(app_log_dir) != 0) { free(app_log_dir); return -1; } else if (any_one_app_log_dir == NULL) { any_one_app_log_dir = app_log_dir; } else { free(app_log_dir); } } if (any_one_app_log_dir == NULL) { fprintf(LOGFILE, "Did not create any app-log directories\n"); return -1; } free(any_one_app_log_dir); ////////////// End of creating the log directories for the app on all disks // open up the credentials file int cred_file = open_file_as_nm(nmPrivate_credentials_file); if (cred_file == -1) { return -1; } // give up root privs if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) { return -1; } // 750 mode_t permissions = S_IRWXU | S_IRGRP | S_IXGRP; char* const* nm_root; char *primary_app_dir = NULL; for(nm_root=local_dirs; *nm_root != NULL; ++nm_root) { char *app_dir = get_app_directory(*nm_root, user, app_id); if (app_dir == NULL) { // try the next one } else if (mkdirs(app_dir, permissions) != 0) { free(app_dir); } else if (primary_app_dir == NULL) { primary_app_dir = app_dir; } else { free(app_dir); } } if (primary_app_dir == NULL) { fprintf(LOGFILE, "Did not create any app directories\n"); return -1; } char *nmPrivate_credentials_file_copy = strdup(nmPrivate_credentials_file); // TODO: FIXME. The user's copy of creds should go to a path selected by // localDirAllocatoir char *cred_file_name = concatenate("%s/%s", "cred file", 2, primary_app_dir, basename(nmPrivate_credentials_file_copy)); if (cred_file_name == NULL) { free(nmPrivate_credentials_file_copy); return -1; } if (copy_file(cred_file, nmPrivate_credentials_file, cred_file_name, S_IRUSR|S_IWUSR) != 0){ free(nmPrivate_credentials_file_copy); return -1; } free(nmPrivate_credentials_file_copy); fclose(stdin); fflush(LOGFILE); if (LOGFILE != stdout) { fclose(stdout); } if (ERRORFILE != stderr) { fclose(stderr); } if (chdir(primary_app_dir) != 0) { fprintf(LOGFILE, "Failed to chdir to app dir - %s\n", strerror(errno)); return -1; } execvp(args[0], args); fprintf(ERRORFILE, "Failure to exec app initialization process - %s\n", strerror(errno)); return -1; }
/** * Function to prepare the container directories. * It creates the container work and log directories. */ static int create_container_directories(const char* user, const char *app_id, const char *container_id, char* const* local_dir, char* const* log_dir, const char *work_dir) { // create dirs as 0750 const mode_t perms = S_IRWXU | S_IRGRP | S_IXGRP; if (app_id == NULL || container_id == NULL || user == NULL) { fprintf(LOGFILE, "Either app_id, container_id or the user passed is null.\n"); return -1; } int result = -1; char* const* local_dir_ptr; for(local_dir_ptr = local_dir; *local_dir_ptr != NULL; ++local_dir_ptr) { char *container_dir = get_container_work_directory(*local_dir_ptr, user, app_id, container_id); if (container_dir == NULL) { return -1; } if (mkdirs(container_dir, perms) == 0) { result = 0; } // continue on to create other work directories free(container_dir); } if (result != 0) { return result; } result = -1; // also make the directory for the container logs char *combined_name = malloc(strlen(app_id) + strlen(container_id) + 2); if (combined_name == NULL) { fprintf(LOGFILE, "Malloc of combined name failed\n"); result = -1; } else { sprintf(combined_name, "%s/%s", app_id, container_id); char* const* log_dir_ptr; for(log_dir_ptr = log_dir; *log_dir_ptr != NULL; ++log_dir_ptr) { char *container_log_dir = get_app_log_directory(*log_dir_ptr, combined_name); if (container_log_dir == NULL) { free(combined_name); return -1; } else if (mkdirs(container_log_dir, perms) != 0) { free(container_log_dir); } else { result = 0; free(container_log_dir); } } free(combined_name); } if (result != 0) { return result; } result = -1; // also make the tmp directory char *tmp_dir = get_tmp_directory(work_dir); if (tmp_dir == NULL) { return -1; } if (mkdirs(tmp_dir, perms) == 0) { result = 0; } free(tmp_dir); return result; }
void test_run_container() { printf("\nTesting run container\n"); if (seteuid(0) != 0) { printf("FAIL: seteuid to root failed - %s\n", strerror(errno)); exit(1); } FILE* creds = fopen(TEST_ROOT "/creds.txt", "w"); if (creds == NULL) { printf("FAIL: failed to create credentials file - %s\n", strerror(errno)); exit(1); } if (fprintf(creds, "secret key\n") < 0) { printf("FAIL: fprintf failed - %s\n", strerror(errno)); exit(1); } if (fclose(creds) != 0) { printf("FAIL: fclose failed - %s\n", strerror(errno)); exit(1); } char * cgroups_pids[] = { TEST_ROOT "/cgroups-pid1.txt", TEST_ROOT "/cgroups-pid2.txt", 0 }; close(creat(cgroups_pids[0], O_RDWR)); close(creat(cgroups_pids[1], O_RDWR)); const char* script_name = TEST_ROOT "/container-script"; FILE* script = fopen(script_name, "w"); if (script == NULL) { printf("FAIL: failed to create script file - %s\n", strerror(errno)); exit(1); } if (seteuid(user_detail->pw_uid) != 0) { printf("FAIL: failed to seteuid back to user - %s\n", strerror(errno)); exit(1); } if (fprintf(script, "#!/bin/bash\n" "touch foobar\n" "exit 0") < 0) { printf("FAIL: fprintf failed - %s\n", strerror(errno)); exit(1); } if (fclose(script) != 0) { printf("FAIL: fclose failed - %s\n", strerror(errno)); exit(1); } fflush(stdout); fflush(stderr); char* container_dir = get_container_work_directory(TEST_ROOT "/local-1", yarn_username, "app_4", "container_1"); const char * pid_file = TEST_ROOT "/pid.txt"; pid_t child = fork(); if (child == -1) { printf("FAIL: failed to fork process for init_app - %s\n", strerror(errno)); exit(1); } else if (child == 0) { if (launch_container_as_user(yarn_username, "app_4", "container_1", container_dir, script_name, TEST_ROOT "/creds.txt", pid_file, local_dirs, log_dirs, "cgroups", cgroups_pids) != 0) { printf("FAIL: failed in child\n"); exit(42); } // should never return exit(1); } int status = 0; if (waitpid(child, &status, 0) <= 0) { printf("FAIL: failed waiting for process %" PRId64 " - %s\n", (int64_t)child, strerror(errno)); exit(1); } if (access(TEST_ROOT "/logs/userlogs/app_4/container_1", R_OK) != 0) { printf("FAIL: failed to create container log directory\n"); exit(1); } if (access(container_dir, R_OK) != 0) { printf("FAIL: failed to create container directory %s\n", container_dir); exit(1); } char buffer[100000]; sprintf(buffer, "%s/foobar", container_dir); if (access(buffer, R_OK) != 0) { printf("FAIL: failed to create touch file %s\n", buffer); exit(1); } free(container_dir); container_dir = get_app_log_directory(TEST_ROOT "/logs/userlogs", "app_4/container_1"); if (access(container_dir, R_OK) != 0) { printf("FAIL: failed to create app log directory %s\n", container_dir); exit(1); } free(container_dir); if (seteuid(0) != 0) { printf("FAIL: seteuid to root failed - %s\n", strerror(errno)); exit(1); } check_pid_file(pid_file, child); check_pid_file(cgroups_pids[0], child); check_pid_file(cgroups_pids[1], child); }
void test_init_app() { printf("\nTesting init app\n"); if (seteuid(0) != 0) { printf("FAIL: seteuid to root failed - %s\n", strerror(errno)); exit(1); } FILE* creds = fopen(TEST_ROOT "/creds.txt", "w"); if (creds == NULL) { printf("FAIL: failed to create credentials file - %s\n", strerror(errno)); exit(1); } if (fprintf(creds, "secret key\n") < 0) { printf("FAIL: fprintf failed - %s\n", strerror(errno)); exit(1); } if (fclose(creds) != 0) { printf("FAIL: fclose failed - %s\n", strerror(errno)); exit(1); } FILE* job_xml = fopen(TEST_ROOT "/job.xml", "w"); if (job_xml == NULL) { printf("FAIL: failed to create job file - %s\n", strerror(errno)); exit(1); } if (fprintf(job_xml, "<jobconf/>\n") < 0) { printf("FAIL: fprintf failed - %s\n", strerror(errno)); exit(1); } if (fclose(job_xml) != 0) { printf("FAIL: fclose failed - %s\n", strerror(errno)); exit(1); } if (seteuid(user_detail->pw_uid) != 0) { printf("FAIL: failed to seteuid back to user - %s\n", strerror(errno)); exit(1); } fflush(stdout); fflush(stderr); pid_t child = fork(); if (child == -1) { printf("FAIL: failed to fork process for init_app - %s\n", strerror(errno)); exit(1); } else if (child == 0) { char *final_pgm[] = {"touch", "my-touch-file", 0}; if (initialize_app(yarn_username, "app_4", TEST_ROOT "/creds.txt", local_dirs, log_dirs, final_pgm) != 0) { printf("FAIL: failed in child\n"); exit(42); } // should never return exit(1); } int status = 0; if (waitpid(child, &status, 0) <= 0) { printf("FAIL: failed waiting for process %" PRId64 " - %s\n", (int64_t)child, strerror(errno)); exit(1); } if (access(TEST_ROOT "/logs/userlogs/app_4", R_OK) != 0) { printf("FAIL: failed to create app log directory\n"); exit(1); } char* app_dir = get_app_directory(TEST_ROOT "/local-1", yarn_username, "app_4"); if (access(app_dir, R_OK) != 0) { printf("FAIL: failed to create app directory %s\n", app_dir); exit(1); } char buffer[100000]; sprintf(buffer, "%s/creds.txt", app_dir); if (access(buffer, R_OK) != 0) { printf("FAIL: failed to create credentials %s\n", buffer); exit(1); } sprintf(buffer, "%s/my-touch-file", app_dir); if (access(buffer, R_OK) != 0) { printf("FAIL: failed to create touch file %s\n", buffer); exit(1); } free(app_dir); app_dir = get_app_log_directory(TEST_ROOT "/logs/userlogs","app_4"); if (access(app_dir, R_OK) != 0) { printf("FAIL: failed to create app log directory %s\n", app_dir); exit(1); } free(app_dir); }
void test_run_container() { printf("\nTesting run container\n"); if (seteuid(0) != 0) { printf("FAIL: seteuid to root failed - %s\n", strerror(errno)); exit(1); } FILE* creds = fopen(TEST_ROOT "/creds.txt", "w"); if (creds == NULL) { printf("FAIL: failed to create credentials file - %s\n", strerror(errno)); exit(1); } if (fprintf(creds, "secret key\n") < 0) { printf("FAIL: fprintf failed - %s\n", strerror(errno)); exit(1); } if (fclose(creds) != 0) { printf("FAIL: fclose failed - %s\n", strerror(errno)); exit(1); } const char* script_name = TEST_ROOT "/container-script"; FILE* script = fopen(script_name, "w"); if (script == NULL) { printf("FAIL: failed to create script file - %s\n", strerror(errno)); exit(1); } if (seteuid(user_detail->pw_uid) != 0) { printf("FAIL: failed to seteuid back to user - %s\n", strerror(errno)); exit(1); } if (fprintf(script, "#!/bin/bash\n" "touch foobar\n" "exit 0") < 0) { printf("FAIL: fprintf failed - %s\n", strerror(errno)); exit(1); } if (fclose(script) != 0) { printf("FAIL: fclose failed - %s\n", strerror(errno)); exit(1); } fflush(stdout); fflush(stderr); char* container_dir = get_container_work_directory(TEST_ROOT "/local-1", username, "app_4", "container_1"); const char * pid_file = TEST_ROOT "/pid.txt"; pid_t child = fork(); if (child == -1) { printf("FAIL: failed to fork process for init_app - %s\n", strerror(errno)); exit(1); } else if (child == 0) { if (launch_container_as_user(username, "app_4", "container_1", container_dir, script_name, TEST_ROOT "/creds.txt", pid_file) != 0) { printf("FAIL: failed in child\n"); exit(42); } // should never return exit(1); } int status = 0; if (waitpid(child, &status, 0) <= 0) { printf("FAIL: failed waiting for process %d - %s\n", child, strerror(errno)); exit(1); } if (access(TEST_ROOT "/logs/userlogs/app_4/container_1", R_OK) != 0) { printf("FAIL: failed to create container log directory\n"); exit(1); } if (access(container_dir, R_OK) != 0) { printf("FAIL: failed to create container directory %s\n", container_dir); exit(1); } char buffer[100000]; sprintf(buffer, "%s/foobar", container_dir); if (access(buffer, R_OK) != 0) { printf("FAIL: failed to create touch file %s\n", buffer); exit(1); } free(container_dir); container_dir = get_app_log_directory("logs", "app_4/container_1"); if (access(container_dir, R_OK) != 0) { printf("FAIL: failed to create app log directory %s\n", container_dir); exit(1); } free(container_dir); if(access(pid_file, R_OK) != 0) { printf("FAIL: failed to create pid file %s\n", pid_file); exit(1); } int pidfd = open(pid_file, O_RDONLY); if (pidfd == -1) { printf("FAIL: failed to open pid file %s - %s\n", pid_file, strerror(errno)); exit(1); } char pidBuf[100]; ssize_t bytes = read(pidfd, pidBuf, 100); if (bytes == -1) { printf("FAIL: failed to read from pid file %s - %s\n", pid_file, strerror(errno)); exit(1); } pid_t mypid = child; char myPidBuf[33]; snprintf(myPidBuf, 33, "%d", mypid); if (strncmp(pidBuf, myPidBuf, strlen(myPidBuf)) != 0) { printf("FAIL: failed to find matching pid in pid file\n"); printf("FAIL: Expected pid %d : Got %.*s", mypid, (int)bytes, pidBuf); exit(1); } }