21
21
#include "utils/docker-util.h"
22
22
#include "utils/path-utils.h"
23
23
#include "utils/string-utils.h"
24
+ #include "runc/runc.h"
24
25
#include "util.h"
25
26
#include "config.h"
26
27
@@ -78,6 +79,7 @@ static const int DEFAULT_DOCKER_SUPPORT_ENABLED = 0;
78
79
static const int DEFAULT_TC_SUPPORT_ENABLED = 0 ;
79
80
static const int DEFAULT_MOUNT_CGROUP_SUPPORT_ENABLED = 0 ;
80
81
static const int DEFAULT_YARN_SYSFS_SUPPORT_ENABLED = 0 ;
82
+ static const int DEFAULT_RUNC_SUPPORT_ENABLED = 0 ;
81
83
82
84
static const char * PROC_PATH = "/proc" ;
83
85
@@ -191,7 +193,7 @@ int check_executor_permissions(char *executable_file) {
191
193
/**
192
194
* Change the effective user id to limit damage.
193
195
*/
194
- static int change_effective_user (uid_t user , gid_t group ) {
196
+ int change_effective_user (uid_t user , gid_t group ) {
195
197
if (geteuid () == user ) {
196
198
return 0 ;
197
199
}
@@ -211,6 +213,10 @@ static int change_effective_user(uid_t user, gid_t group) {
211
213
return 0 ;
212
214
}
213
215
216
+ int change_effective_user_to_nm () {
217
+ return change_effective_user (nm_uid , nm_gid );
218
+ }
219
+
214
220
#ifdef __linux
215
221
/**
216
222
* Write the pid of the current process to the cgroup file.
@@ -408,7 +414,7 @@ static int wait_and_get_exit_code(pid_t pid) {
408
414
* the exit code file.
409
415
* Returns the exit code of the container process.
410
416
*/
411
- static int wait_and_write_exit_code (pid_t pid , const char * exit_code_file ) {
417
+ int wait_and_write_exit_code (pid_t pid , const char * exit_code_file ) {
412
418
int exit_code = -1 ;
413
419
414
420
exit_code = wait_and_get_exit_code (pid );
@@ -510,6 +516,12 @@ int is_yarn_sysfs_support_enabled() {
510
516
DEFAULT_YARN_SYSFS_SUPPORT_ENABLED , & executor_cfg );
511
517
}
512
518
519
+ int is_runc_support_enabled () {
520
+ return is_feature_enabled (RUNC_SUPPORT_ENABLED_KEY ,
521
+ DEFAULT_RUNC_SUPPORT_ENABLED , & executor_cfg )
522
+ || runc_module_enabled (& CFG );
523
+ }
524
+
513
525
/**
514
526
* Utility function to concatenate argB to argA using the concat_pattern.
515
527
*/
@@ -642,6 +654,20 @@ char *get_tmp_directory(const char *work_dir) {
642
654
return concatenate ("%s/%s" , "tmp dir" , 2 , work_dir , TMP_DIR );
643
655
}
644
656
657
+ /**
658
+ * Get the private /tmp directory under the working directory
659
+ */
660
+ char * get_privatetmp_directory (const char * work_dir ) {
661
+ return concatenate ("%s/%s" , "private /tmp dir" , 2 , work_dir , ROOT_TMP_DIR );
662
+ }
663
+
664
+ /**
665
+ * Get the private /tmp directory under the working directory
666
+ */
667
+ char * get_private_var_tmp_directory (const char * work_dir ) {
668
+ return concatenate ("%s/%s" , "private /var/tmp dir" , 2 , work_dir , ROOT_VAR_TMP_DIR );
669
+ }
670
+
645
671
/**
646
672
* Ensure that the given path and all of the parent directories are created
647
673
* with the desired permissions.
@@ -810,17 +836,51 @@ static int create_container_directories(const char* user, const char *app_id,
810
836
return result ;
811
837
}
812
838
813
- result = COULD_NOT_CREATE_TMP_DIRECTORIES ;
814
839
// also make the tmp directory
815
840
char * tmp_dir = get_tmp_directory (work_dir );
841
+ char * private_tmp_dir = get_privatetmp_directory (work_dir );
842
+ char * private_var_tmp_dir = get_private_var_tmp_directory (work_dir );
816
843
817
- if (tmp_dir == NULL ) {
844
+ if (tmp_dir == NULL || private_tmp_dir == NULL || private_var_tmp_dir == NULL ) {
818
845
return OUT_OF_MEMORY ;
819
846
}
820
- if (mkdirs (tmp_dir , perms ) == 0 ) {
821
- result = 0 ;
847
+
848
+ if (mkdirs (tmp_dir , perms ) != 0 ) {
849
+ fprintf (ERRORFILE , "Could not create tmp_dir: %s\n" , tmp_dir );
850
+ result = COULD_NOT_CREATE_TMP_DIRECTORIES ;
851
+ goto cleanup ;
852
+ }
853
+
854
+ if (mkdirs (private_tmp_dir , perms ) != 0 ) {
855
+ fprintf (ERRORFILE , "Could not create private_tmp_dir: %s\n" , private_tmp_dir );
856
+ result = COULD_NOT_CREATE_TMP_DIRECTORIES ;
857
+ goto cleanup ;
858
+ }
859
+
860
+ // clear group sticky bit on private_tmp_dir
861
+ if (chmod (private_tmp_dir , perms ) != 0 ) {
862
+ fprintf (ERRORFILE , "Could not chmod private_tmp_dir: %s\n" , private_tmp_dir );
863
+ result = COULD_NOT_CREATE_TMP_DIRECTORIES ;
864
+ goto cleanup ;
865
+ }
866
+
867
+ if (mkdirs (private_var_tmp_dir , perms ) != 0 ) {
868
+ fprintf (ERRORFILE , "Could not create private_var_tmp_dir: %s\n" , private_var_tmp_dir );
869
+ result = COULD_NOT_CREATE_TMP_DIRECTORIES ;
870
+ goto cleanup ;
871
+ }
872
+
873
+ // clear group sticky bit on private_tmp_dir
874
+ if (chmod (private_var_tmp_dir , perms ) != 0 ) {
875
+ fprintf (ERRORFILE , "Could not chmod private_var_tmp_dir: %s\n" , private_var_tmp_dir );
876
+ result = COULD_NOT_CREATE_TMP_DIRECTORIES ;
877
+ goto cleanup ;
822
878
}
879
+
880
+ cleanup :
823
881
free (tmp_dir );
882
+ free (private_tmp_dir );
883
+ free (private_var_tmp_dir );
824
884
825
885
return result ;
826
886
}
@@ -1051,6 +1111,36 @@ static int open_file_as_nm(const char* filename) {
1051
1111
return result ;
1052
1112
}
1053
1113
1114
+ /**
1115
+ * Check the pidfile as the node manager. File should not exist.
1116
+ * Returns 0 on file doesn't exist and -1 on file does exist.
1117
+ */
1118
+ int check_pidfile_as_nm (const char * pidfile ) {
1119
+ int result = 0 ;
1120
+ uid_t user = geteuid ();
1121
+ gid_t group = getegid ();
1122
+ if (change_effective_user (nm_uid , nm_gid ) != 0 ) {
1123
+ return -1 ;
1124
+ }
1125
+
1126
+ struct stat statbuf ;
1127
+ if (stat (pidfile , & statbuf ) == 0 ) {
1128
+ fprintf (ERRORFILE , "pid file already exists: %s\n" , pidfile );
1129
+ result = -1 ;
1130
+ }
1131
+
1132
+ if (errno != ENOENT ) {
1133
+ fprintf (ERRORFILE , "Error accessing %s : %s\n" , pidfile ,
1134
+ strerror (errno ));
1135
+ result = -1 ;
1136
+ }
1137
+
1138
+ if (change_effective_user (user , group )) {
1139
+ result = -1 ;
1140
+ }
1141
+ return result ;
1142
+ }
1143
+
1054
1144
/**
1055
1145
* Copy a file from a fd to a given filename.
1056
1146
* The new file must not exist and it is created with permissions perm.
@@ -1863,6 +1953,61 @@ int create_yarn_sysfs(const char* user, const char *app_id,
1863
1953
return result ;
1864
1954
}
1865
1955
1956
+ int setup_container_paths (const char * user , const char * app_id ,
1957
+ const char * container_id , const char * work_dir , const char * script_name ,
1958
+ const char * cred_file , int https , const char * keystore_file , const char * truststore_file ,
1959
+ char * const * local_dirs , char * const * log_dirs ) {
1960
+ char * script_file_dest = NULL ;
1961
+ char * cred_file_dest = NULL ;
1962
+ char * keystore_file_dest = NULL ;
1963
+ char * truststore_file_dest = NULL ;
1964
+ int container_file_source = -1 ;
1965
+ int cred_file_source = -1 ;
1966
+ int keystore_file_source = -1 ;
1967
+ int truststore_file_source = -1 ;
1968
+
1969
+ int result = initialize_user (user , local_dirs );
1970
+ if (result != 0 ) {
1971
+ return result ;
1972
+ }
1973
+
1974
+ int rc = create_script_paths (
1975
+ work_dir , script_name , cred_file , https , keystore_file , truststore_file , & script_file_dest , & cred_file_dest ,
1976
+ & keystore_file_dest , & truststore_file_dest , & container_file_source , & cred_file_source , & keystore_file_source , & truststore_file_source );
1977
+
1978
+ if (rc != 0 ) {
1979
+ fputs ("Could not create script path\n" , ERRORFILE );
1980
+ goto cleanup ;
1981
+ }
1982
+
1983
+ rc = create_log_dirs (app_id , log_dirs );
1984
+ if (rc != 0 ) {
1985
+ fputs ("Could not create log files and directories\n" , ERRORFILE );
1986
+ goto cleanup ;
1987
+ }
1988
+
1989
+ rc = create_local_dirs (user , app_id , container_id ,
1990
+ work_dir , script_name , cred_file , https , keystore_file , truststore_file , local_dirs , log_dirs ,
1991
+ 1 , script_file_dest , cred_file_dest , keystore_file_dest , truststore_file_dest ,
1992
+ container_file_source , cred_file_source , keystore_file_source , truststore_file_source );
1993
+
1994
+ if (rc != 0 ) {
1995
+ fputs ("Could not create local files and directories\n" , ERRORFILE );
1996
+ goto cleanup ;
1997
+ }
1998
+
1999
+ rc = create_yarn_sysfs (user , app_id , container_id , work_dir , local_dirs );
2000
+ if (rc != 0 ) {
2001
+ fputs ("Could not create user yarn sysfs directory\n" , ERRORFILE );
2002
+ goto cleanup ;
2003
+ }
2004
+
2005
+ cleanup :
2006
+ free (script_file_dest );
2007
+ free (cred_file_dest );
2008
+ return rc ;
2009
+ }
2010
+
1866
2011
int launch_docker_container_as_user (const char * user , const char * app_id ,
1867
2012
const char * container_id , const char * work_dir ,
1868
2013
const char * script_name , const char * cred_file ,
0 commit comments