Пример #1
0
    def get_create_job_log_path(cls, suite, task_name, task_point, submit_num):
        """Return a new job log path on the suite host, in two parts.

        /part1/part2

        * part1: the top level job log directory on the suite host.
        * part2: the rest, which is also used on remote task hosts.

        The full local job log directory is created if necessary, and its
        parent symlinked to NN (submit number).

        """

        suite_job_log_dir = GLOBAL_CFG.get_derived_host_item(
            suite, "suite job log directory")

        the_rest_dir = os.path.join(
            str(task_point), task_name, "%02d" % int(submit_num))
        the_rest = os.path.join(the_rest_dir, "job")

        local_log_dir = os.path.join(suite_job_log_dir, the_rest_dir)

        mkdir_p(local_log_dir)
        target = os.path.join(os.path.dirname(local_log_dir), "NN")
        try:
            os.unlink(target)
        except OSError:
            pass
        try:
            os.symlink(os.path.basename(local_log_dir), target)
        except OSError as exc:
            if not exc.filename:
                exc.filename = target
            raise exc
        return suite_job_log_dir, the_rest
Пример #2
0
 def create_directory(self, d, name):
     try:
         mkdir_p(d)
     except Exception, x:
         print >> sys.stderr, str(x)
         raise GlobalConfigError(
             'Failed to create directory "' + name + '"')
Пример #3
0
    def update(self):
        #print "Attempting Update"
        if ( self.last_update_time is not None and
             self.last_update_time >= self.updater.last_update_time ):
            if self.action_required:
                return True
            return False
        
        if self.updater.status == "stopped":
            gobject.idle_add(self.connection_lost)
            return False

        self.updater.set_update(False)
        self.task_list = deepcopy(self.updater.task_list)
        self.live_graph_movie = self.updater.live_graph_movie
        self.live_graph_dir = self.updater.live_graph_dir
        states_full = deepcopy(self.updater.state_summary)
        fam_states_full = deepcopy(self.updater.fam_state_summary)
        self.ancestors = deepcopy(self.updater.ancestors)
        self.descendants = deepcopy(self.updater.descendants)
        self.all_families = deepcopy(self.updater.all_families)
        self.triggering_families = deepcopy(self.updater.triggering_families)
        self.global_summary = deepcopy(self.updater.global_summary)
        self.updater.set_update(True)

        if self.last_update_time is None:
            self.first_update = True
            if self.live_graph_movie:
                try:
                    mkdir_p( self.live_graph_dir )
                except Exception, x:
                    print >> sys.stderr, x
                    print >> sys.stderr, "Disabling live graph movie"
                    self.live_graph_movie = False
Пример #4
0
 def create_directory(self, d, name):
     try:
         mkdir_p(d)
     except Exception, x:
         print >> sys.stderr, str(x)
         raise GlobalConfigError(
             'Failed to create directory "' + name + '"')
Пример #5
0
    def _dump_passphrase_to_dir(self, path, passphrase=None):
        """Dump passphrase to "passphrase" file in "path".

        1. File permission should already be user-read-write-only on
           creation by mkstemp.
        2. The combination of os.fsync and os.rename should guarentee
           that we don't end up with an incomplete passphrase file.
        3. Perhaps we should use uuid.uuid4() to generate the passphrase?
        """
        mkdir_p(path)
        from tempfile import NamedTemporaryFile
        handle = NamedTemporaryFile(
            prefix=self.PASSPHRASE_FILE_BASE, dir=path, delete=False)
        # Note: Perhaps a UUID might be better here?
        if passphrase is None:
            import random
            passphrase = ''.join(
                random.sample(self.PASSPHRASE_CHARSET, self.PASSPHRASE_LEN))
        handle.write(passphrase)
        os.fsync(handle.fileno())
        handle.close()
        passphrase_file_name = os.path.join(
            path, self.PASSPHRASE_FILE_BASE)
        os.rename(handle.name, passphrase_file_name)
        if cylc.flags.verbose:
            print 'Generated suite passphrase: %s' % passphrase_file_name
Пример #6
0
    def _job_submit_prepare_remote(self, job_file_path):
        """Prepare a remote job file.

        On remote mode, write job file, content from STDIN Modify job
        script's CYLC_DIR for this host. Extract job submission method
        and job submission command template.

        Return (batch_sys_name, batch_sys_submit)

        """
        batch_sys_name = None
        batch_submit_cmd_tmpl = None
        mkdir_p(os.path.dirname(job_file_path))
        job_file = open(job_file_path + ".tmp", "w")
        while True:  # Note: "for line in sys.stdin:" may hang
            line = sys.stdin.readline()
            if not line:
                sys.stdin.close()
                break
            if line.startswith(self.LINE_PREFIX_CYLC_DIR):
                old_line = line
                line = "%s'%s'\n" % (self.LINE_PREFIX_CYLC_DIR, os.environ["CYLC_DIR"])
                if old_line != line:
                    job_file.write(self.LINE_UPDATE_CYLC_DIR)
            elif line.startswith(self.LINE_PREFIX_BATCH_SYS_NAME):
                batch_sys_name = line.replace(self.LINE_PREFIX_BATCH_SYS_NAME, "").strip()
            elif line.startswith(self.LINE_PREFIX_BATCH_SUBMIT_CMD_TMPL):
                batch_submit_cmd_tmpl = line.replace(self.LINE_PREFIX_BATCH_SUBMIT_CMD_TMPL, "").strip()
            job_file.write(line)
        job_file.close()
        os.rename(job_file_path + ".tmp", job_file_path)
        os.chmod(job_file_path, (os.stat(job_file_path).st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH))
        return batch_sys_name, batch_submit_cmd_tmpl
Пример #7
0
def remote_init(uuid_str, rund):
    """cylc remote-init

    Arguments:
        uuid_str (str): suite host UUID
        rund (str): suite run directory
    """
    rund = os.path.expandvars(rund)
    srvd = os.path.join(rund, SuiteSrvFilesManager.DIR_BASE_SRV)
    try:
        orig_uuid_str = open(os.path.join(srvd, 'uuid')).read()
    except IOError:
        pass
    else:
        if orig_uuid_str == uuid_str:
            print(REMOTE_INIT_NOT_REQUIRED)
            return
    mkdir_p(rund)
    oldcwd = os.getcwd()
    os.chdir(rund)
    try:
        tarhandle = tarfile.open(fileobj=sys.stdin, mode='r|')
        tarhandle.extractall()
        tarhandle.close()
    finally:
        os.chdir(oldcwd)
    print(REMOTE_INIT_DONE)
    return
Пример #8
0
def remote_init(uuid_str, rund, indirect_comm=None):
    """cylc remote-init

    Arguments:
        uuid_str (str): suite host UUID
        rund (str): suite run directory
        *indirect_comm (str): use indirect communication via e.g. 'ssh'
    """
    rund = os.path.expandvars(rund)
    srvd = os.path.join(rund, SuiteSrvFilesManager.DIR_BASE_SRV)
    try:
        orig_uuid_str = open(os.path.join(srvd, FILE_BASE_UUID)).read()
    except IOError:
        pass
    else:
        if orig_uuid_str == uuid_str:
            print(REMOTE_INIT_NOT_REQUIRED)
            return
    mkdir_p(rund)
    oldcwd = os.getcwd()
    os.chdir(rund)
    try:
        tarhandle = tarfile.open(fileobj=sys.stdin, mode='r|')
        tarhandle.extractall()
        tarhandle.close()
    finally:
        os.chdir(oldcwd)
    if indirect_comm:
        fname = os.path.join(srvd, SuiteSrvFilesManager.FILE_BASE_CONTACT2)
        with open(fname, 'w') as handle:
            handle.write(
                '%s=%s\n' %
                (SuiteSrvFilesManager.KEY_COMMS_PROTOCOL_2, indirect_comm))
    print(REMOTE_INIT_DONE)
    return
Пример #9
0
def remote_init(uuid_str, rund, indirect_comm=None):
    """cylc remote-init

    Arguments:
        uuid_str (str): suite host UUID
        rund (str): suite run directory
        *indirect_comm (str): use indirect communication via e.g. 'ssh'
    """
    rund = os.path.expandvars(rund)
    srvd = os.path.join(rund, SuiteSrvFilesManager.DIR_BASE_SRV)
    try:
        orig_uuid_str = open(os.path.join(srvd, FILE_BASE_UUID)).read()
    except IOError:
        pass
    else:
        if orig_uuid_str == uuid_str:
            print(REMOTE_INIT_NOT_REQUIRED)
            return
    mkdir_p(rund)
    oldcwd = os.getcwd()
    os.chdir(rund)
    try:
        tarhandle = tarfile.open(fileobj=sys.stdin, mode='r|')
        tarhandle.extractall()
        tarhandle.close()
    finally:
        os.chdir(oldcwd)
    if indirect_comm:
        fname = os.path.join(srvd, SuiteSrvFilesManager.FILE_BASE_CONTACT2)
        with open(fname, 'w') as handle:
            handle.write('%s=%s\n' % (
                SuiteSrvFilesManager.KEY_COMMS_PROTOCOL_2, indirect_comm))
    print(REMOTE_INIT_DONE)
    return
Пример #10
0
    def get_create_job_log_path(cls, suite, task_name, task_point, submit_num):
        """Return a new job log path on the suite host, in two parts.

        /part1/part2

        * part1: the top level job log directory on the suite host.
        * part2: the rest, which is also used on remote task hosts.

        The full local job log directory is created if necessary, and its
        parent symlinked to NN (submit number).

        """

        suite_job_log_dir = GLOBAL_CFG.get_derived_host_item(
            suite, "suite job log directory")

        the_rest_dir = os.path.join(str(task_point), task_name,
                                    "%02d" % int(submit_num))
        the_rest = os.path.join(the_rest_dir, "job")

        local_log_dir = os.path.join(suite_job_log_dir, the_rest_dir)

        mkdir_p(local_log_dir)
        target = os.path.join(os.path.dirname(local_log_dir), "NN")
        try:
            os.unlink(target)
        except OSError:
            pass
        try:
            os.symlink(os.path.basename(local_log_dir), target)
        except OSError as exc:
            if not exc.filename:
                exc.filename = target
            raise exc
        return suite_job_log_dir, the_rest
Пример #11
0
 def create_directory(dir_, name):
     """Create directory. Raise GlobalConfigError on error."""
     try:
         mkdir_p(dir_)
     except OSError as exc:
         LOG.exception(exc)
         raise GlobalConfigError('Failed to create directory "' + name +
                                 '"')
Пример #12
0
 def create_directory(dir_, name):
     """Create directory. Raise GlobalConfigError on error."""
     try:
         mkdir_p(dir_)
     except OSError as exc:
         print >> sys.stderr, str(exc)
         raise GlobalConfigError(
             'Failed to create directory "' + name + '"')
Пример #13
0
 def create_directory(self, d, name):
     """Create directory. Raise GlobalConfigError on error."""
     try:
         mkdir_p(d)
     except Exception, exc:
         print >> sys.stderr, str(exc)
         raise GlobalConfigError(
             'Failed to create directory "' + name + '"')
Пример #14
0
 def create_directory(dir_, name):
     """Create directory. Raise GlobalConfigError on error."""
     try:
         mkdir_p(dir_)
     except OSError as exc:
         print >> sys.stderr, str(exc)
         raise GlobalConfigError('Failed to create directory "' + name +
                                 '"')
Пример #15
0
 def create_directory(self, d, name):
     """Create directory. Raise GlobalConfigError on error."""
     try:
         mkdir_p(d)
     except Exception, exc:
         print >> sys.stderr, str(exc)
         raise GlobalConfigError('Failed to create directory "' + name +
                                 '"')
Пример #16
0
 def append_to_log(self, submit_num, log_type, out=None, err=None):
     """Write new command output to the appropriate log file."""
     sub_num = "%02d" % int(submit_num)
     dir_ = os.path.join(self.base_path, sub_num)
     mkdir_p(dir_)
     job_log_handle = open(os.path.join(dir_, "job-activity.log"), "a")
     timestamp = get_current_time_string()
     self._write_to_log(job_log_handle, timestamp, log_type + "-OUT", out)
     self._write_to_log(job_log_handle, timestamp, log_type + "-ERR", err)
     job_log_handle.close()
Пример #17
0
 def append_to_log(self, submit_num, log_type, out=None, err=None):
     """Write new command output to the appropriate log file."""
     sub_num = "%02d" % int(submit_num)
     dir_ = os.path.join(self.base_path, sub_num)
     mkdir_p(dir_)
     job_log_handle = open(os.path.join(dir_, "job-activity.log"), "a")
     timestamp = get_current_time_string()
     self._write_to_log(job_log_handle, timestamp, log_type + "-OUT", out)
     self._write_to_log(job_log_handle, timestamp, log_type + "-ERR", err)
     job_log_handle.close()
Пример #18
0
 def __init__(self, dbpath=None):
     self.dbpath = dbpath or REGDB_PATH
     # create initial database directory if necessary
     if not os.path.exists(self.dbpath):
         try:
             mkdir_p(self.dbpath)
         except OSError as exc:
             sys.exit(str(exc))
     self.local_passphrases = set()
     self.cached_passphrases = {}
     self.can_disk_cache_passphrases = {}
Пример #19
0
 def toggle_write_dot_frames(self):
     self.write_dot_frames = not self.write_dot_frames
     if self.write_dot_frames:
         # Create local share dir if necessary (could be a remote suite).
         try:
             mkdir_p(self.suite_share_dir)
         except Exception as exc:
             gobject.idle_add(warning_dialog(
                 "%s\nCannot create graph frames directory." % (str(exc))
             ).warn)
             self.write_dot_frames = False
Пример #20
0
 def toggle_write_dot_frames(self):
     self.write_dot_frames = not self.write_dot_frames
     if self.write_dot_frames:
         # Create local share dir if necessary (could be a remote suite).
         try:
             mkdir_p(self.suite_share_dir)
         except Exception as exc:
             gobject.idle_add(warning_dialog(
                 "%s\nCannot create graph frames directory." % (str(exc))
             ).warn)
             self.write_dot_frames = False
    def register(self, reg, source=None):
        """Generate service files for a suite. Record its source location."""
        self.detect_old_contact_file(reg)
        srv_d = self.get_suite_srv_dir(reg)
        target = os.path.join(srv_d, self.FILE_BASE_SOURCE)
        if source is None:
            try:
                # No change if already registered
                source_str = os.readlink(target)
            except OSError:
                # Source path is assumed to be the run directory
                source_str = ".."
        else:
            # Tidy source path
            if os.path.basename(source) == self.FILE_BASE_SUITE_RC:
                source = os.path.dirname(source)
            if not os.path.isabs(source):
                # On AIX on GPFS os.path.abspath(source) returns the source
                # with full 'fileset' prefix. Manual use of $PWD to absolutize
                # a relative path gives a cleaner result.
                source = os.path.join(os.getenv("PWD", os.getcwd()), source)
            source = os.path.normpath(source)
            if (os.path.abspath(source) == os.path.abspath(
                    os.path.dirname(srv_d))):
                source_str = ".."
            else:
                source_str = source
        # Create target if it does not exist.
        # Re-create target if it does not point to specified source.
        mkdir_p(srv_d)
        try:
            orig_source_str = os.readlink(target)
        except OSError:
            os.symlink(source_str, target)
        else:
            if orig_source_str != source_str:
                os.unlink(target)
                os.symlink(source_str, target)

        # Create a new passphrase for the suite if necessary.
        if not self._locate_item(self.FILE_BASE_PASSPHRASE, srv_d):
            import random
            self._dump_item(
                srv_d, self.FILE_BASE_PASSPHRASE, ''.join(
                    random.sample(self.PASSPHRASE_CHARSET,
                                  self.PASSPHRASE_LEN)))

        # Load or create SSL private key for the suite.
        pkey_obj = self._get_ssl_pem(srv_d)

        # Load or create SSL certificate for the suite.
        self._get_ssl_cert(srv_d, pkey_obj)
Пример #22
0
    def register(self, reg, source=None):
        """Generate service files for a suite. Record its source location."""
        self.detect_old_contact_file(reg)
        srv_d = self.get_suite_srv_dir(reg)
        target = os.path.join(srv_d, self.FILE_BASE_SOURCE)
        if source is None:
            try:
                # No change if already registered
                source_str = os.readlink(target)
            except OSError:
                # Source path is assumed to be the run directory
                source_str = ".."
        else:
            # Tidy source path
            if os.path.basename(source) == self.FILE_BASE_SUITE_RC:
                source = os.path.dirname(source)
            if not os.path.isabs(source):
                # On AIX on GPFS os.path.abspath(source) returns the source
                # with full 'fileset' prefix. Manual use of $PWD to absolutize
                # a relative path gives a cleaner result.
                source = os.path.join(os.getenv("PWD", os.getcwd()), source)
            source = os.path.normpath(source)
            if (os.path.abspath(source) ==
                    os.path.abspath(os.path.dirname(srv_d))):
                source_str = ".."
            else:
                source_str = source
        # Create target if it does not exist.
        # Re-create target if it does not point to specified source.
        mkdir_p(srv_d)
        try:
            orig_source_str = os.readlink(target)
        except OSError:
            os.symlink(source_str, target)
        else:
            if orig_source_str != source_str:
                os.unlink(target)
                os.symlink(source_str, target)

        # Create a new passphrase for the suite if necessary.
        if not self._locate_item(self.FILE_BASE_PASSPHRASE, srv_d):
            import random
            self._dump_item(srv_d, self.FILE_BASE_PASSPHRASE, ''.join(
                random.sample(self.PASSPHRASE_CHARSET, self.PASSPHRASE_LEN)))

        # Load or create SSL private key for the suite.
        pkey_obj = self._get_ssl_pem(srv_d)

        # Load or create SSL certificate for the suite.
        self._get_ssl_cert(srv_d, pkey_obj)
Пример #23
0
    def reconnect( self ):

        self.prev_graph_id = ()
        try:
            client = cylc_pyro_client.client( 
                    self.cfg.suite,
                    self.cfg.pphrase,
                    self.cfg.owner,
                    self.cfg.host,
                    self.cfg.pyro_timeout,
                    self.cfg.port )
            self.god = client.get_proxy( 'state_summary' )
            self.sinfo = client.get_proxy( 'suite-info' )

            # on reconnection retrieve static info
            self.family_nodes = self.sinfo.get( 'family nodes' )
            self.graphed_family_nodes = self.sinfo.get( 'graphed family nodes' )
            self.descendants = self.sinfo.get( 'first-parent descendants' )
            self.ancestors = self.sinfo.get('first-parent ancestors' )
            self.live_graph_movie, self.live_graph_dir = self.sinfo.get( 'do live graph movie' )
        except:
            # connection lost
            if self.stop_summary is None:
                self.stop_summary = dump.get_stop_state_summary(
                                                            self.cfg.suite,
                                                            self.cfg.owner,
                                                            self.cfg.host)
                if self.stop_summary is not None and any(self.stop_summary):
                    self.info_bar.set_stop_summary(self.stop_summary)
            return False
        else: 
            self.stop_summary = None
            self.status = "connected"
            self.first_update = True
            self.info_bar.set_status( self.status )
            if self.live_graph_movie:
                try:
                    mkdir_p( self.live_graph_dir )
                except Exception, x:
                    print >> sys.stderr, x
                    print >> sys.stderr, "Disabling live graph movie"
                    self.live_graph_movie = False
            self.first_update = True
            self.status = "connected"
            self.poll_schd.stop()
            self.info_bar.set_status( self.status )
            return True
Пример #24
0
    def _dump_item(path, item, value):
        """Dump "value" to a file called "item" in the directory "path".

        1. File permission should already be user-read-write-only on
           creation by mkstemp.
        2. The combination of os.fsync and os.rename should guarantee
           that we don't end up with an incomplete file.
        """
        mkdir_p(path)
        from tempfile import NamedTemporaryFile
        handle = NamedTemporaryFile(prefix=item, dir=path, delete=False)
        handle.write(value)
        os.fsync(handle.fileno())
        handle.close()
        fname = os.path.join(path, item)
        os.rename(handle.name, fname)
        LOG.debug('Generated %s', fname)
Пример #25
0
    def create_auth_files(self, reg):
        """Create or renew passphrase and SSL files for suite 'reg'."""
        # Suite service directory.
        srv_d = self.get_suite_srv_dir(reg)
        mkdir_p(srv_d)

        # Create a new passphrase for the suite if necessary.
        if not self._locate_item(self.FILE_BASE_PASSPHRASE, srv_d):
            import random
            self._dump_item(
                srv_d, self.FILE_BASE_PASSPHRASE, ''.join(
                    random.sample(self.PASSPHRASE_CHARSET,
                                  self.PASSPHRASE_LEN)))
        # Load or create SSL private key for the suite.
        pkey_obj = self._get_ssl_pem(srv_d)
        # Load or create SSL certificate for the suite.
        self._get_ssl_cert(srv_d, pkey_obj)
Пример #26
0
    def _dump_item(self, path, item, value):
        """Dump "value" to a file called "item" in the directory "path".

        1. File permission should already be user-read-write-only on
           creation by mkstemp.
        2. The combination of os.fsync and os.rename should guarentee
           that we don't end up with an incomplete file.
        """
        mkdir_p(path)
        from tempfile import NamedTemporaryFile
        handle = NamedTemporaryFile(prefix=item, dir=path, delete=False)
        handle.write(value)
        os.fsync(handle.fileno())
        handle.close()
        fname = os.path.join(path, item)
        os.rename(handle.name, fname)
        if cylc.flags.verbose:
            print 'Generated %s' % fname
Пример #27
0
    def _create_job_log_path(self, suite, itask):
        """Create job log directory for a task job, etc.

        Create local job directory, and NN symbolic link.
        If NN => 01, remove numbered directories with submit numbers greater
        than 01.
        Return a string in the form "POINT/NAME/SUBMIT_NUM".

        """
        job_file_dir = self.task_events_mgr.get_task_job_log(
            suite, itask.point, itask.tdef.name, itask.submit_num)
        task_log_dir = os.path.dirname(job_file_dir)
        if itask.submit_num == 1:
            try:
                names = os.listdir(task_log_dir)
            except OSError:
                pass
            else:
                for name in names:
                    if name not in ["01", self.task_events_mgr.NN]:
                        rmtree(
                            os.path.join(task_log_dir, name),
                            ignore_errors=True)
        else:
            rmtree(job_file_dir, ignore_errors=True)

        mkdir_p(job_file_dir)
        target = os.path.join(task_log_dir, self.task_events_mgr.NN)
        source = os.path.basename(job_file_dir)
        try:
            prev_source = os.readlink(target)
        except OSError:
            prev_source = None
        if prev_source == source:
            return
        try:
            if prev_source:
                os.unlink(target)
            os.symlink(source, target)
        except OSError as exc:
            if not exc.filename:
                exc.filename = target
            raise exc
Пример #28
0
    def _create_job_log_path(self, suite, itask):
        """Create job log directory for a task job, etc.

        Create local job directory, and NN symbolic link.
        If NN => 01, remove numbered directories with submit numbers greater
        than 01.
        Return a string in the form "POINT/NAME/SUBMIT_NUM".

        """
        job_file_dir = self.task_events_mgr.get_task_job_log(
            suite, itask.point, itask.tdef.name, itask.submit_num)
        task_log_dir = os.path.dirname(job_file_dir)
        if itask.submit_num == 1:
            try:
                names = os.listdir(task_log_dir)
            except OSError:
                pass
            else:
                for name in names:
                    if name not in ["01", self.task_events_mgr.NN]:
                        rmtree(
                            os.path.join(task_log_dir, name),
                            ignore_errors=True)
        else:
            rmtree(job_file_dir, ignore_errors=True)

        mkdir_p(job_file_dir)
        target = os.path.join(task_log_dir, self.task_events_mgr.NN)
        source = os.path.basename(job_file_dir)
        try:
            prev_source = os.readlink(target)
        except OSError:
            prev_source = None
        if prev_source == source:
            return
        try:
            if prev_source:
                os.unlink(target)
            os.symlink(source, target)
        except OSError as exc:
            if not exc.filename:
                exc.filename = target
            raise exc
Пример #29
0
 def generate(self, dir):
     pfile = os.path.join(dir, 'passphrase')
     if os.path.isfile(pfile):
         try:
             self.get(pfile)
             return
         except PassphraseError:
             pass
     # Note: Perhaps a UUID might be better here?
     char_set = string.ascii_uppercase + string.ascii_lowercase + string.digits
     self.passphrase = ''.join(random.sample(char_set, 20))
     mkdir_p(dir)
     f = open(pfile, 'w')
     f.write(self.passphrase)
     f.close()
     # set passphrase file permissions to owner-only
     os.chmod(pfile, 0600)
     if cylc.flags.verbose:
         print 'Generated suite passphrase: %s@%s:%s' % (
             user, get_hostname(), pfile)
Пример #30
0
    def _job_submit_prepare_remote(self, job_file_path):
        """Prepare a remote job file.

        On remote mode, write job file, content from STDIN Modify job
        script's CYLC_DIR for this host. Extract job submission method
        and job submission command template.

        Return (batch_sys_name, batch_sys_submit)

        """
        batch_sys_name = None
        submit_opts = {}
        mkdir_p(os.path.dirname(job_file_path))
        job_file = open(job_file_path + ".tmp", "w")
        while True:  # Note: "for line in sys.stdin:" may hang
            line = sys.stdin.readline()
            if not line:
                sys.stdin.close()
                break
            if line.startswith(self.LINE_PREFIX_CYLC_DIR):
                old_line = line
                line = "%s'%s'\n" % (self.LINE_PREFIX_CYLC_DIR,
                                     os.environ["CYLC_DIR"])
                if old_line != line:
                    job_file.write(self.LINE_UPDATE_CYLC_DIR)
            elif line.startswith(self.LINE_PREFIX_BATCH_SYS_NAME):
                batch_sys_name = line.replace(self.LINE_PREFIX_BATCH_SYS_NAME,
                                              "").strip()
            elif line.startswith(self.LINE_PREFIX_BATCH_SUBMIT_CMD_TMPL):
                submit_opts["batch_submit_cmd_tmpl"] = line.replace(
                    self.LINE_PREFIX_BATCH_SUBMIT_CMD_TMPL, "").strip()
            elif line.startswith(self.LINE_PREFIX_EXECUTION_TIME_LIMIT):
                submit_opts["execution_time_limit"] = float(
                    line.replace(self.LINE_PREFIX_BATCH_SUBMIT_CMD_TMPL,
                                 "").strip())
            job_file.write(line)
        job_file.close()
        os.rename(job_file_path + ".tmp", job_file_path)
        os.chmod(job_file_path, (os.stat(job_file_path).st_mode | stat.S_IXUSR
                                 | stat.S_IXGRP | stat.S_IXOTH))
        return batch_sys_name, submit_opts
Пример #31
0
 def do_rollover(self):
     """Create and rollover log file if necessary."""
     # Generate new file name
     self.stamp = get_current_time_string(use_basic_format=True)
     filename = self.baseFilename + '.' + self.stamp
     mkdir_p(os.path.dirname(filename))
     # Touch file
     with open(filename, 'w+'):
         os.utime(filename, None)
     # Update symlink
     if (os.path.exists(self.baseFilename)
             or os.path.lexists(self.baseFilename)):
         os.unlink(self.baseFilename)
     os.symlink(os.path.basename(filename), self.baseFilename)
     # Housekeep log files
     arch_len = glbl_cfg().get([self.GLBL_KEY, 'rolling archive length'])
     if arch_len:
         log_files = glob(self.baseFilename + '.*')
         log_files.sort()
         while len(log_files) > arch_len:
             os.unlink(log_files.pop(0))
     # Reopen stream, redirect STDOUT and STDERR to log
     if self.stream:
         self.stream.close()
         self.stream = None
     self.stream = self._open()
     # Dup STDOUT and STDERR in detach mode
     if not self.no_detach:
         os.dup2(self.stream.fileno(), sys.stdout.fileno())
         os.dup2(self.stream.fileno(), sys.stderr.fileno())
     # Emit header records (should only do this for subsequent log files)
     for header_record in self.header_records:
         if self.FILE_NUM in header_record.__dict__:
             # Increment log file number
             header_record.__dict__[self.FILE_NUM] += 1
             header_record.args = header_record.args[0:-1] + (
                 header_record.__dict__[self.FILE_NUM], )
         logging.FileHandler.emit(self, header_record)
Пример #32
0
    def reconnect( self ):
 
        try:
            client = cylc_pyro_client.client( 
                    self.cfg.suite,
                    self.cfg.pphrase,
                    self.cfg.owner,
                    self.cfg.host,
                    self.cfg.pyro_timeout,
                    self.cfg.port )
            self.god = client.get_proxy( 'state_summary' )
            self.remote = client.get_proxy( 'remote' )
        except:
            if self.stop_summary is None:
                self.stop_summary = dump.get_stop_state_summary(
                                                            self.cfg.suite,
                                                            self.cfg.owner,
                                                            self.cfg.host)
                if any(self.stop_summary):
                    self.info_bar.set_stop_summary(self.stop_summary)
            return False
        else:
            self.stop_summary = None
            self.family_nodes = self.remote.get_family_nodes()
            self.graphed_family_nodes = self.remote.get_graphed_family_nodes()
            self.families = self.remote.get_families()
            self.live_graph_movie, self.live_graph_dir = self.remote.do_live_graph_movie()
            if self.live_graph_movie:
                try:
                    mkdir_p( self.live_graph_dir )
                except Exception, x:
                    print >> sys.stderr, x
                    raise SuiteConfigError, 'ERROR, illegal dir? ' + self.live_graph_dir 

            self.status = "connected"
            self.info_bar.set_status( self.status )
            return True
Пример #33
0
    def update(self):
        if not self.updater.connected:
            if not self.cleared:
                gobject.idle_add(self.clear_graph)
                self.cleared = True
            return False
        self.cleared = False

        if ( self.last_update_time is not None and
             self.last_update_time >= self.updater.last_update_time ):
            if self.action_required:
                return True
            return False

        self.updater.set_update(False)
        self.task_list = deepcopy(self.updater.task_list)
        self.live_graph_movie = self.updater.live_graph_movie
        self.live_graph_dir = self.updater.live_graph_dir
        states_full = deepcopy(self.updater.state_summary)
        fam_states_full = deepcopy(self.updater.fam_state_summary)
        self.ancestors = deepcopy(self.updater.ancestors)
        self.descendants = deepcopy(self.updater.descendants)
        self.all_families = deepcopy(self.updater.all_families)
        self.triggering_families = deepcopy(self.updater.triggering_families)
        self.global_summary = deepcopy(self.updater.global_summary)
        self.updater.set_update(True)

        if self.last_update_time is None:
            self.first_update = True
            if self.live_graph_movie:
                try:
                    mkdir_p( self.live_graph_dir )
                except Exception, x:
                    print >> sys.stderr, x
                    print >> sys.stderr, "Disabling live graph movie"
                    self.live_graph_movie = False
Пример #34
0
    def _dump_certificate_and_key_to_dir(self, path, suite):
        """Dump SSL certificate to "ssl.cert" file in "path"."""
        try:
            from OpenSSL import crypto
        except ImportError:
            # OpenSSL not installed, so we can't use HTTPS anyway.
            return
        host = get_hostname()
        altnames = ["DNS:*", "DNS:%s" % host,
                    "IP:%s" % get_local_ip_address(host)]
        # Workaround for https://github.com/kennethreitz/requests/issues/2621
        altnames.append("DNS:%s" % get_local_ip_address(host))

        # Use suite name as the 'common name', but no more than 64 chars.
        cert_common_name = suite
        if len(suite) > 64:
            cert_common_name = suite[:61] + "..."

        # Create a private key.
        pkey_obj = crypto.PKey()
        pkey_obj.generate_key(crypto.TYPE_RSA, 2048)

        # Create a self-signed certificate.
        cert_obj = crypto.X509()
        cert_obj.get_subject().O = "Cylc"
        cert_obj.get_subject().CN = cert_common_name
        cert_obj.gmtime_adj_notBefore(0)
        cert_obj.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60)  # 10 years.
        cert_obj.set_issuer(cert_obj.get_subject())
        cert_obj.set_pubkey(pkey_obj)
        cert_obj.add_extensions([
            crypto.X509Extension(
                "subjectAltName", False, ", ".join(altnames)
            )
        ])
        cert_obj.sign(pkey_obj, 'sha256')

        mkdir_p(path)

        # Work in a user-read-write-only directory for guaranteed safety.
        from tempfile import mkdtemp
        work_dir = mkdtemp()
        pkey_file = os.path.join(work_dir, self.SSL_PRIVATE_KEY_FILE_BASE)
        cert_file = os.path.join(work_dir, self.SSL_CERTIFICATE_FILE_BASE)

        with open(pkey_file, "w") as file_handle:
            file_handle.write(
                crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey_obj))
        with open(cert_file, "w") as file_handle:
            file_handle.write(
                crypto.dump_certificate(crypto.FILETYPE_PEM, cert_obj))

        import stat
        os.chmod(pkey_file, stat.S_IRUSR)
        os.chmod(cert_file, stat.S_IRUSR)
        pkey_dest_file = os.path.join(path, self.SSL_PRIVATE_KEY_FILE_BASE)
        cert_dest_file = os.path.join(path, self.SSL_CERTIFICATE_FILE_BASE)
        import shutil
        shutil.copy(pkey_file, pkey_dest_file)
        shutil.copy(cert_file, cert_dest_file)
        shutil.rmtree(work_dir)
        if cylc.flags.verbose:
            print 'Generated suite SSL certificate: %s' % cert_dest_file
            print 'Generated suite SSL private key: %s' % pkey_dest_file
Пример #35
0
    def _jobs_submit_prep_by_stdin(self, job_log_root, job_log_dirs):
        """Prepare job files for submit by reading from STDIN.

        Job files are uploaded via STDIN in remote mode. Modify job
        files' CYLC_DIR for this host. Extract job submission methods
        and job submission command templates from each job file.

        Return a list, where each element contains something like:
        (job_log_dir, batch_sys_name, submit_opts)

        """
        items = [[job_log_dir, None, {}] for job_log_dir in job_log_dirs]
        items_map = {}
        for item in items:
            items_map[item[0]] = item
        handle = None
        batch_sys_name = None
        submit_opts = {}
        job_log_dir = None
        lines = []
        # Get job files from STDIN.
        # Modify CYLC_DIR in job file, if necessary.
        # Get batch system name and batch submit command template from each job
        # file.
        # Write job file in correct location.
        while True:  # Note: "for cur_line in sys.stdin:" may hang
            cur_line = sys.stdin.readline()
            if not cur_line:
                if handle is not None:
                    handle.close()
                break

            if cur_line.startswith(self.LINE_PREFIX_CYLC_DIR):
                old_line = cur_line
                cur_line = "%s'%s'\n" % (
                    self.LINE_PREFIX_CYLC_DIR, os.environ["CYLC_DIR"])
                if old_line != cur_line:
                    lines.append(self.LINE_UPDATE_CYLC_DIR)
            elif cur_line.startswith(self.LINE_PREFIX_BATCH_SYS_NAME):
                batch_sys_name = cur_line.replace(
                    self.LINE_PREFIX_BATCH_SYS_NAME, "").strip()
            elif cur_line.startswith(self.LINE_PREFIX_BATCH_SUBMIT_CMD_TMPL):
                submit_opts["batch_submit_cmd_tmpl"] = cur_line.replace(
                    self.LINE_PREFIX_BATCH_SUBMIT_CMD_TMPL, "").strip()
            elif cur_line.startswith(self.LINE_PREFIX_EXECUTION_TIME_LIMIT):
                submit_opts["execution_time_limit"] = float(cur_line.replace(
                    self.LINE_PREFIX_EXECUTION_TIME_LIMIT, "").strip())
            elif cur_line.startswith(self.LINE_PREFIX_JOB_LOG_DIR):
                job_log_dir = cur_line.replace(
                    self.LINE_PREFIX_JOB_LOG_DIR, "").strip()
                mkdir_p(os.path.join(job_log_root, job_log_dir))
                handle = open(
                    os.path.join(job_log_root, job_log_dir, "job.tmp"), "wb")

            if handle is None:
                lines.append(cur_line)
            else:
                for line in lines + [cur_line]:
                    handle.write(line)
                lines = []
                if cur_line.startswith(self.LINE_PREFIX_EOF + job_log_dir):
                    handle.close()
                    # Make it executable
                    os.chmod(handle.name, (
                        os.stat(handle.name).st_mode |
                        stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH))
                    # Rename from "*/job.tmp" to "*/job"
                    os.rename(handle.name, handle.name[:-4])
                    try:
                        items_map[job_log_dir][1] = batch_sys_name
                        items_map[job_log_dir][2] = submit_opts
                    except KeyError:
                        pass
                    handle = None
                    job_log_dir = None
                    batch_sys_name = None
                    submit_opts = {}
        return items
Пример #36
0
Much of the information here should ultimately end up in a sensible 
site and host configuration file or similar.
"""

# PYRO CONFIGURATION ###################################################
# base port (the lowest allowed socket number)
pyro_base_port = 7766  # (7766 is the Pyro default)
# max number of ports starting from base port
pyro_port_range = 100  # (100 is the Pyro default)

# SUITE REGISTRATION DATABASE LOCATION #################################
# Local registrations, user-specific
local_regdb_path = os.path.join(os.environ["HOME"], ".cylc", "DB")

# CYLC TEMPORARY DIRECTORY #############################################
try:
    cylc_tmpdir = os.environ["CYLC_TMPDIR"]
except KeyError:
    # use tempfile.mkdtemp() to create a new temp directory
    cylc_tmpdir = mkdtemp(prefix="cylc-")
    atexit.register(lambda: shutil.rmtree(cylc_tmpdir))
else:
    # if CYLC_TMPDIR was set, create the dir if necessary
    try:
        mkdir_p(cylc_tmpdir)
    except Exception, x:
        print >>sys.stderr, x
        print >>sys.stderr, "ERROR, conf/CylcGlobals.py: illegal temp dir?", cylc_tmpdir
        sys.exit(1)
# print "Cylc Temp Dir is:", cylc_tmpdir
Пример #37
0
    def register(self, reg=None, source=None, redirect=False):
        """Register a suite, or renew its registration.

        Create suite service directory and symlink to suite source location.

        Args:
            reg (str): suite name, default basename($PWD).
            source (str): directory location of suite.rc file, default $PWD.
            redirect (bool): allow reuse of existing name and run directory.

        Return:
            The registered suite name (which may be computed here).

        Raise:
            SuiteServiceFileError:
                No suite.rc file found in source location.
                Illegal name (can look like a relative path, but not absolute).
                Another suite already has this name (unless --redirect).
        """
        if reg is None:
            reg = os.path.basename(os.getcwd())

        if os.path.isabs(reg):
            raise SuiteServiceFileError(
                "ERROR: suite name cannot be an absolute path: %s" % reg)

        if source is not None:
            if os.path.basename(source) == self.FILE_BASE_SUITE_RC:
                source = os.path.dirname(source)
        else:
            source = os.getcwd()

        # suite.rc must exist so we can detect accidentally reversed args.
        source = os.path.abspath(source)
        if not os.path.isfile(os.path.join(source, self.FILE_BASE_SUITE_RC)):
            raise SuiteServiceFileError("ERROR: no suite.rc in %s" % source)

        # Create service dir if necessary.
        srv_d = self.get_suite_srv_dir(reg)
        mkdir_p(srv_d)

        # See if suite already has a source or not
        try:
            orig_source = os.readlink(
                os.path.join(srv_d, self.FILE_BASE_SOURCE))
        except OSError:
            orig_source = None
        else:
            if not os.path.isabs(orig_source):
                orig_source = os.path.normpath(os.path.join(
                    srv_d, orig_source))
        if orig_source is not None and source != orig_source:
            if not redirect:
                raise SuiteServiceFileError(
                    "ERROR: the name '%s' already points to %s.\nUse "
                    "--redirect to re-use an existing name and run "
                    "directory." % (reg, orig_source))
            LOG.warning(
                "the name '%(reg)s' points to %(old)s.\nIt will now"
                " be redirected to %(new)s.\nFiles in the existing %(reg)s run"
                " directory will be overwritten.\n", {
                    'reg': reg,
                    'old': orig_source,
                    'new': source
                })
            # Remove symlink to the original suite.
            os.unlink(os.path.join(srv_d, self.FILE_BASE_SOURCE))

        # Create symlink to the suite, if it doesn't already exist.
        if orig_source is None or source != orig_source:
            target = os.path.join(srv_d, self.FILE_BASE_SOURCE)
            if (os.path.abspath(source) == os.path.abspath(
                    os.path.dirname(srv_d))):
                # If source happens to be the run directory,
                # create .service/source -> ..
                source_str = ".."
            else:
                source_str = source
            os.symlink(source_str, target)

        print('REGISTERED %s -> %s' % (reg, source))
        return reg
Пример #38
0
    def _jobs_submit_prep_by_stdin(self, job_log_root, job_log_dirs):
        """Prepare job files for submit by reading from STDIN.

        Job files are uploaded via STDIN in remote mode. Modify job
        files' CYLC_DIR for this host. Extract job submission methods
        and job submission command templates from each job file.

        Return a list, where each element contains something like:
        (job_log_dir, batch_sys_name, submit_opts)

        """
        items = [[job_log_dir, None, {}] for job_log_dir in job_log_dirs]
        items_map = {}
        for item in items:
            items_map[item[0]] = item
        handle = None
        batch_sys_name = None
        submit_opts = {}
        job_log_dir = None
        lines = []
        # Get job files from STDIN.
        # Modify CYLC_DIR in job file, if necessary.
        # Get batch system name and batch submit command template from each job
        # file.
        # Write job file in correct location.
        while True:  # Note: "for cur_line in sys.stdin:" may hang
            cur_line = sys.stdin.readline()
            if not cur_line:
                if handle is not None:
                    handle.close()
                break

            if cur_line.startswith(self.LINE_PREFIX_CYLC_DIR):
                old_line = cur_line
                cur_line = "%s'%s'\n" % (
                    self.LINE_PREFIX_CYLC_DIR, os.environ["CYLC_DIR"])
                if old_line != cur_line:
                    lines.append(self.LINE_UPDATE_CYLC_DIR)
            elif cur_line.startswith(self.LINE_PREFIX_BATCH_SYS_NAME):
                batch_sys_name = cur_line.replace(
                    self.LINE_PREFIX_BATCH_SYS_NAME, "").strip()
            elif cur_line.startswith(self.LINE_PREFIX_BATCH_SUBMIT_CMD_TMPL):
                submit_opts["batch_submit_cmd_tmpl"] = cur_line.replace(
                    self.LINE_PREFIX_BATCH_SUBMIT_CMD_TMPL, "").strip()
            elif cur_line.startswith(self.LINE_PREFIX_EXECUTION_TIME_LIMIT):
                submit_opts["execution_time_limit"] = float(cur_line.replace(
                    self.LINE_PREFIX_EXECUTION_TIME_LIMIT, "").strip())
            elif cur_line.startswith(self.LINE_PREFIX_JOB_LOG_DIR):
                job_log_dir = cur_line.replace(
                    self.LINE_PREFIX_JOB_LOG_DIR, "").strip()
                mkdir_p(os.path.join(job_log_root, job_log_dir))
                handle = open(
                    os.path.join(job_log_root, job_log_dir, "job.tmp"), "wb")

            if handle is None:
                lines.append(cur_line)
            else:
                for line in lines + [cur_line]:
                    handle.write(line)
                lines = []
                if cur_line.startswith(self.LINE_PREFIX_EOF + job_log_dir):
                    handle.close()
                    # Make it executable
                    os.chmod(handle.name, (
                        os.stat(handle.name).st_mode |
                        stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH))
                    # Rename from "*/job.tmp" to "*/job"
                    os.rename(handle.name, handle.name[:-4])
                    try:
                        items_map[job_log_dir][1] = batch_sys_name
                        items_map[job_log_dir][2] = submit_opts
                    except KeyError:
                        pass
                    handle = None
                    job_log_dir = None
                    batch_sys_name = None
                    submit_opts = {}
        return items