##// END OF EJS Templates
Fixing how the working directory is handled in kernel....
Brian Granger -
Show More
@@ -47,22 +47,19 b' c = get_config()'
47 47
48 48 # The working directory for the process. The application will use os.chdir
49 49 # to change to this directory before starting.
50 # c.Global.working_dir = os.getcwd()
50 # c.Global.work_dir = os.getcwd()
51 51
52 52
53 53 #-----------------------------------------------------------------------------
54 54 # Local process launchers
55 55 #-----------------------------------------------------------------------------
56 56
57 # The working directory for the controller
58 # c.LocalControllerLauncher.working_dir = u''
59
60 57 # The command line arguments to call the controller with.
61 58 # c.LocalControllerLauncher.controller_args = \
62 59 # ['--log-to-file','--log-level', '40']
63 60
64 61 # The working directory for the controller
65 # c.LocalEngineSetLauncher.working_dir = u''
62 # c.LocalEngineSetLauncher.work_dir = u''
66 63
67 64 # Command line argument passed to the engines.
68 65 # c.LocalEngineSetLauncher.engine_args = ['--log-to-file','--log-level', '40']
@@ -71,9 +68,6 b' c = get_config()'
71 68 # MPIExec launchers
72 69 #-----------------------------------------------------------------------------
73 70
74 # The working directory for the controller
75 # c.MPIExecControllerLauncher.working_dir = u''
76
77 71 # The mpiexec/mpirun command to use in started the controller.
78 72 # c.MPIExecControllerLauncher.mpi_cmd = ['mpiexec']
79 73
@@ -85,9 +79,6 b' c = get_config()'
85 79 # ['--log-to-file','--log-level', '40']
86 80
87 81
88 # The working directory for the controller
89 # c.MPIExecEngineSetLauncher.working_dir = u''
90
91 82 # The mpiexec/mpirun command to use in started the controller.
92 83 # c.MPIExecEngineSetLauncher.mpi_cmd = ['mpiexec']
93 84
@@ -111,9 +102,6 b' c = get_config()'
111 102 # Unix batch (PBS) schedulers launchers
112 103 #-----------------------------------------------------------------------------
113 104
114 # The working directory for the controller
115 # c.PBSControllerLauncher.working_dir = u''
116
117 105 # The command line program to use to submit a PBS job.
118 106 # c.PBSControllerLauncher.submit_command = 'qsub'
119 107
@@ -125,8 +113,8 b' c = get_config()'
125 113
126 114 # The batch submission script used to start the controller. This is where
127 115 # environment variables would be setup, etc. This string is interpolated using
128 # the Itpl module in IPython.external. Basically, you can use ${profile} for
129 # the controller profile or ${cluster_dir} for the cluster_dir.
116 # the Itpl module in IPython.external. Basically, you can use ${n} for the
117 # number of engine and ${cluster_dir} for the cluster_dir.
130 118 # c.PBSControllerLauncher.batch_template = """"""
131 119
132 120 # The name of the instantiated batch script that will actually be used to
@@ -134,9 +122,6 b' c = get_config()'
134 122 # c.PBSControllerLauncher.batch_file_name = u'pbs_batch_script_controller'
135 123
136 124
137 # The working directory for the controller
138 # c.PBSEngineSetLauncher.working_dir = u''
139
140 125 # The command line program to use to submit a PBS job.
141 126 # c.PBSEngineSetLauncher.submit_command = 'qsub'
142 127
@@ -149,8 +134,7 b' c = get_config()'
149 134 # The batch submission script used to start the engines. This is where
150 135 # environment variables would be setup, etc. This string is interpolated using
151 136 # the Itpl module in IPython.external. Basically, you can use ${n} for the
152 # number of engine, ${profile} or the engine profile and ${cluster_dir}
153 # for the cluster_dir.
137 # number of engine and ${cluster_dir} for the cluster_dir.
154 138 # c.PBSEngineSetLauncher.batch_template = """"""
155 139
156 140 # The name of the instantiated batch script that will actually be used to
@@ -173,7 +157,6 b' c = get_config()'
173 157 # c.IPControllerTask.controller_args = ['--log-to-file', '--log-level', '40']
174 158 # c.IPControllerTask.environment_variables = {}
175 159
176 # c.WindowsHPCControllerLauncher.working_dir = u''
177 160 # c.WindowsHPCControllerLauncher.scheduler = 'HEADNODE'
178 161 # c.WindowsHPCControllerLauncher.job_file_name = u'ipcontroller_job.xml'
179 162
@@ -190,7 +173,6 b' c = get_config()'
190 173 # c.IPEngineTask.engine_args = ['--log-to-file', '--log-level', '40']
191 174 # c.IPEngineTask.environment_variables = {}
192 175
193 # c.WindowsHPCEngineSetLauncher.working_dir = u''
194 176 # c.WindowsHPCEngineSetLauncher.scheduler = 'HEADNODE'
195 177 # c.WindowsHPCEngineSetLauncher.job_file_name = u'ipengineset_job.xml'
196 178
@@ -37,7 +37,7 b' c = get_config()'
37 37
38 38 # The working directory for the process. The application will use os.chdir
39 39 # to change to this directory before starting.
40 # c.Global.working_dir = os.getcwd()
40 # c.Global.work_dir = os.getcwd()
41 41
42 42 #-----------------------------------------------------------------------------
43 43 # Configure the client services
@@ -36,7 +36,7 b' c = get_config()'
36 36
37 37 # The working directory for the process. The application will use os.chdir
38 38 # to change to this directory before starting.
39 # c.Global.working_dir = os.getcwd()
39 # c.Global.work_dir = os.getcwd()
40 40
41 41 #-----------------------------------------------------------------------------
42 42 # MPI configuration
@@ -257,11 +257,11 b' class AppWithClusterDirArgParseConfigLoader(ArgParseConfigLoader):'
257 257 default=NoConfigDefault,
258 258 metavar='Global.cluster_dir'
259 259 ),
260 self.parser.add_argument('--working-dir',
261 dest='Global.working_dir',type=unicode,
260 self.parser.add_argument('--work-dir',
261 dest='Global.work_dir',type=unicode,
262 262 help='Set the working dir for the process.',
263 263 default=NoConfigDefault,
264 metavar='Global.working_dir'
264 metavar='Global.work_dir'
265 265 )
266 266 self.parser.add_argument('--clean-logs',
267 267 dest='Global.clean_logs', action='store_true',
@@ -299,7 +299,7 b' class ApplicationWithClusterDir(Application):'
299 299 super(ApplicationWithClusterDir, self).create_default_config()
300 300 self.default_config.Global.profile = u'default'
301 301 self.default_config.Global.cluster_dir = u''
302 self.default_config.Global.working_dir = os.getcwd()
302 self.default_config.Global.work_dir = os.getcwd()
303 303 self.default_config.Global.log_to_file = False
304 304 self.default_config.Global.clean_logs = False
305 305
@@ -405,13 +405,13 b' class ApplicationWithClusterDir(Application):'
405 405 pdir = self.cluster_dir_obj.pid_dir
406 406 self.pid_dir = config.Global.pid_dir = pdir
407 407 self.log.info("Cluster directory set to: %s" % self.cluster_dir)
408 config.Global.working_dir = unicode(genutils.expand_path(config.Global.working_dir))
408 config.Global.work_dir = unicode(genutils.expand_path(config.Global.work_dir))
409 409 # Change to the working directory. We do this just before construct
410 410 # is called so all the components there have the right working dir.
411 self.to_working_dir()
411 self.to_work_dir()
412 412
413 def to_working_dir(self):
414 wd = self.master_config.Global.working_dir
413 def to_work_dir(self):
414 wd = self.master_config.Global.work_dir
415 415 if unicode(wd) != unicode(os.getcwd()):
416 416 os.chdir(wd)
417 417 self.log.info("Changing to working dir: %s" % wd)
@@ -86,11 +86,11 b' class IPClusterCLLoader(ArgParseConfigLoader):'
86 86 '--profile option.',
87 87 default=NoConfigDefault,
88 88 metavar='Global.cluster_dir'),
89 parent_parser2.add_argument('--working-dir',
90 dest='Global.working_dir',type=unicode,
89 parent_parser2.add_argument('--work-dir',
90 dest='Global.work_dir',type=unicode,
91 91 help='Set the working dir for the process.',
92 92 default=NoConfigDefault,
93 metavar='Global.working_dir')
93 metavar='Global.work_dir')
94 94 parent_parser2.add_argument('--log-to-file',
95 95 action='store_true', dest='Global.log_to_file',
96 96 default=NoConfigDefault,
@@ -247,7 +247,7 b' class IPClusterApp(ApplicationWithClusterDir):'
247 247 print start_cmd + " ==> " + full_path
248 248
249 249 def pre_construct(self):
250 # This is where we cd to the working directory.
250 # IPClusterApp.pre_construct() is where we cd to the working directory.
251 251 super(IPClusterApp, self).pre_construct()
252 252 config = self.master_config
253 253 try:
@@ -272,14 +272,17 b' class IPClusterApp(ApplicationWithClusterDir):'
272 272 def start_launchers(self):
273 273 config = self.master_config
274 274
275 # Create the launchers
275 # Create the launchers. In both bases, we set the work_dir of
276 # the launcher to the cluster_dir. This is where the launcher's
277 # subprocesses will be launched. It is not where the controller
278 # and engine will be launched.
276 279 el_class = import_item(config.Global.engine_launcher)
277 280 self.engine_launcher = el_class(
278 self.cluster_dir, config=config
281 work_dir=self.cluster_dir, config=config
279 282 )
280 283 cl_class = import_item(config.Global.controller_launcher)
281 284 self.controller_launcher = cl_class(
282 self.cluster_dir, config=config
285 work_dir=self.cluster_dir, config=config
283 286 )
284 287
285 288 # Setup signals
@@ -99,11 +99,18 b' class UnknownStatus(LauncherError):'
99 99 class BaseLauncher(Component):
100 100 """An asbtraction for starting, stopping and signaling a process."""
101 101
102 working_dir = Unicode(u'')
103
104 def __init__(self, working_dir, parent=None, name=None, config=None):
102 # In all of the launchers, the work_dir is where child processes will be
103 # run. This will usually be the cluster_dir, but may not be. any work_dir
104 # passed into the __init__ method will override the config value.
105 # This should not be used to set the work_dir for the actual engine
106 # and controller. Instead, use their own config files or the
107 # controller_args, engine_args attributes of the launchers to add
108 # the --work-dir option.
109 work_dir = Unicode(u'')
110
111 def __init__(self, work_dir, parent=None, name=None, config=None):
105 112 super(BaseLauncher, self).__init__(parent, name, config)
106 self.working_dir = working_dir
113 self.work_dir = work_dir
107 114 self.state = 'before' # can be before, running, after
108 115 self.stop_deferreds = []
109 116 self.start_data = None
@@ -270,16 +277,16 b' class LocalProcessLauncher(BaseLauncher):'
270 277 """Start and stop an external process in an asynchronous manner.
271 278
272 279 This will launch the external process with a working directory of
273 ``self.working_dir``.
280 ``self.work_dir``.
274 281 """
275 282
276 283 # This is used to to construct self.args, which is passed to
277 284 # spawnProcess.
278 285 cmd_and_args = List([])
279 286
280 def __init__(self, working_dir, parent=None, name=None, config=None):
287 def __init__(self, work_dir, parent=None, name=None, config=None):
281 288 super(LocalProcessLauncher, self).__init__(
282 working_dir, parent, name, config
289 work_dir, parent, name, config
283 290 )
284 291 self.process_protocol = None
285 292 self.start_deferred = None
@@ -296,7 +303,7 b' class LocalProcessLauncher(BaseLauncher):'
296 303 str(self.args[0]), # twisted expects these to be str, not unicode
297 304 [str(a) for a in self.args], # str expected, not unicode
298 305 env=os.environ,
299 path=self.working_dir # start in the working_dir
306 path=self.work_dir # start in the work_dir
300 307 )
301 308 return self.start_deferred
302 309 else:
@@ -331,8 +338,7 b' class LocalControllerLauncher(LocalProcessLauncher):'
331 338 controller_args = List(['--log-to-file','--log-level', '40'], config=True)
332 339
333 340 def find_args(self):
334 return self.controller_cmd + self.controller_args + \
335 ['--working-dir', self.working_dir]
341 return self.controller_cmd + self.controller_args
336 342
337 343 def start(self, cluster_dir):
338 344 """Start the controller by cluster_dir."""
@@ -352,8 +358,7 b' class LocalEngineLauncher(LocalProcessLauncher):'
352 358 )
353 359
354 360 def find_args(self):
355 return self.engine_cmd + self.engine_args + \
356 ['--working-dir', self.working_dir]
361 return self.engine_cmd + self.engine_args
357 362
358 363 def start(self, cluster_dir):
359 364 """Start the engine by cluster_dir."""
@@ -370,9 +375,9 b' class LocalEngineSetLauncher(BaseLauncher):'
370 375 ['--log-to-file','--log-level', '40'], config=True
371 376 )
372 377
373 def __init__(self, working_dir, parent=None, name=None, config=None):
378 def __init__(self, work_dir, parent=None, name=None, config=None):
374 379 super(LocalEngineSetLauncher, self).__init__(
375 working_dir, parent, name, config
380 work_dir, parent, name, config
376 381 )
377 382 self.launchers = []
378 383
@@ -381,7 +386,7 b' class LocalEngineSetLauncher(BaseLauncher):'
381 386 self.cluster_dir = unicode(cluster_dir)
382 387 dlist = []
383 388 for i in range(n):
384 el = LocalEngineLauncher(self.working_dir, self)
389 el = LocalEngineLauncher(self.work_dir, self)
385 390 # Copy the engine args over to each engine launcher.
386 391 import copy
387 392 el.engine_args = copy.deepcopy(self.engine_args)
@@ -471,8 +476,7 b' class MPIExecControllerLauncher(MPIExecLauncher):'
471 476
472 477 def find_args(self):
473 478 return self.mpi_cmd + ['-n', self.n] + self.mpi_args + \
474 self.controller_cmd + self.controller_args + \
475 ['--working-dir', self.working_dir]
479 self.controller_cmd + self.controller_args
476 480
477 481
478 482 class MPIExecEngineSetLauncher(MPIExecLauncher):
@@ -481,20 +485,20 b' class MPIExecEngineSetLauncher(MPIExecLauncher):'
481 485 # Command line arguments for ipengine.
482 486 engine_args = List(
483 487 ['--log-to-file','--log-level', '40'], config=True
484 )
488 )
485 489 n = Int(1, config=True)
486 490
487 491 def start(self, n, cluster_dir):
488 492 """Start n engines by profile or cluster_dir."""
489 493 self.engine_args.extend(['--cluster-dir', cluster_dir])
490 494 self.cluster_dir = unicode(cluster_dir)
495 self.n = n
491 496 log.msg('Starting MPIExecEngineSetLauncher: %r' % self.args)
492 497 return super(MPIExecEngineSetLauncher, self).start(n)
493 498
494 499 def find_args(self):
495 500 return self.mpi_cmd + ['-n', self.n] + self.mpi_args + \
496 self.engine_cmd + self.engine_args + \
497 ['--working-dir', self.working_dir]
501 self.engine_cmd + self.engine_args
498 502
499 503
500 504 #-----------------------------------------------------------------------------
@@ -565,20 +569,20 b' class WindowsHPCLauncher(BaseLauncher):'
565 569 # The filename of the instantiated job script.
566 570 job_file_name = Unicode(u'ipython_job.xml', config=True)
567 571 # The full path to the instantiated job script. This gets made dynamically
568 # by combining the working_dir with the job_file_name.
572 # by combining the work_dir with the job_file_name.
569 573 job_file = Unicode(u'')
570 574 # The hostname of the scheduler to submit the job to
571 575 scheduler = Str('', config=True)
572 576 job_cmd = Str(find_job_cmd(), config=True)
573 577
574 def __init__(self, working_dir, parent=None, name=None, config=None):
578 def __init__(self, work_dir, parent=None, name=None, config=None):
575 579 super(WindowsHPCLauncher, self).__init__(
576 working_dir, parent, name, config
580 work_dir, parent, name, config
577 581 )
578 582
579 583 @property
580 584 def job_file(self):
581 return os.path.join(self.working_dir, self.job_file_name)
585 return os.path.join(self.work_dir, self.job_file_name)
582 586
583 587 def write_job_file(self, n):
584 588 raise NotImplementedError("Implement write_job_file in a subclass.")
@@ -611,7 +615,7 b' class WindowsHPCLauncher(BaseLauncher):'
611 615 output = yield getProcessOutput(str(self.job_cmd),
612 616 [str(a) for a in args],
613 617 env=dict((str(k),str(v)) for k,v in os.environ.items()),
614 path=self.working_dir
618 path=self.work_dir
615 619 )
616 620 job_id = self.parse_job_id(output)
617 621 self.notify_start(job_id)
@@ -630,7 +634,7 b' class WindowsHPCLauncher(BaseLauncher):'
630 634 output = yield getProcessOutput(str(self.job_cmd),
631 635 [str(a) for a in args],
632 636 env=dict((str(k),str(v)) for k,v in os.environ.items()),
633 path=self.working_dir
637 path=self.work_dir
634 638 )
635 639 except:
636 640 output = 'The job already appears to be stoppped: %r' % self.job_id
@@ -651,7 +655,7 b' class WindowsHPCControllerLauncher(WindowsHPCLauncher):'
651 655 # the controller. It is used as the base path for the stdout/stderr
652 656 # files that the scheduler redirects to.
653 657 t.work_directory = self.cluster_dir
654 # Add the --cluster-dir and --working-dir from self.start().
658 # Add the --cluster-dir and from self.start().
655 659 t.controller_args.extend(self.extra_args)
656 660 job.add_task(t)
657 661
@@ -664,9 +668,7 b' class WindowsHPCControllerLauncher(WindowsHPCLauncher):'
664 668
665 669 def start(self, cluster_dir):
666 670 """Start the controller by cluster_dir."""
667 self.extra_args = [
668 '--cluster-dir', cluster_dir, '--working-dir', self.working_dir
669 ]
671 self.extra_args = ['--cluster-dir', cluster_dir]
670 672 self.cluster_dir = unicode(cluster_dir)
671 673 return super(WindowsHPCControllerLauncher, self).start(1)
672 674
@@ -685,7 +687,7 b' class WindowsHPCEngineSetLauncher(WindowsHPCLauncher):'
685 687 # the engine. It is used as the base path for the stdout/stderr
686 688 # files that the scheduler redirects to.
687 689 t.work_directory = self.cluster_dir
688 # Add the --cluster-dir and --working-dir from self.start().
690 # Add the --cluster-dir and from self.start().
689 691 t.engine_args.extend(self.extra_args)
690 692 job.add_task(t)
691 693
@@ -698,9 +700,7 b' class WindowsHPCEngineSetLauncher(WindowsHPCLauncher):'
698 700
699 701 def start(self, n, cluster_dir):
700 702 """Start the controller by cluster_dir."""
701 self.extra_args = [
702 '--cluster-dir', cluster_dir, '--working-dir', self.working_dir
703 ]
703 self.extra_args = ['--cluster-dir', cluster_dir]
704 704 self.cluster_dir = unicode(cluster_dir)
705 705 return super(WindowsHPCEngineSetLauncher, self).start(n)
706 706
@@ -739,11 +739,11 b' class BatchSystemLauncher(BaseLauncher):'
739 739 # The full path to the instantiated batch script.
740 740 batch_file = Unicode(u'')
741 741
742 def __init__(self, working_dir, parent=None, name=None, config=None):
742 def __init__(self, work_dir, parent=None, name=None, config=None):
743 743 super(BatchSystemLauncher, self).__init__(
744 working_dir, parent, name, config
744 work_dir, parent, name, config
745 745 )
746 self.batch_file = os.path.join(self.working_dir, self.batch_file_name)
746 self.batch_file = os.path.join(self.work_dir, self.batch_file_name)
747 747 self.context = {}
748 748
749 749 def parse_job_id(self, output):
@@ -758,7 +758,7 b' class BatchSystemLauncher(BaseLauncher):'
758 758 return job_id
759 759
760 760 def write_batch_script(self, n):
761 """Instantiate and write the batch script to the working_dir."""
761 """Instantiate and write the batch script to the work_dir."""
762 762 self.context['n'] = n
763 763 script_as_string = Itpl.itplns(self.batch_template, self.context)
764 764 log.msg('Writing instantiated batch script: %s' % self.batch_file)
@@ -14,7 +14,7 b' executed.'
14 14 # the file COPYING, distributed as part of this software.
15 15 #*****************************************************************************
16 16
17 # TODO: deprecated
17
18 18 def prefilter_shell(self,line,continuation):
19 19 """Alternate prefilter, modified for shell-like functionality.
20 20
General Comments 0
You need to be logged in to leave comments. Login now