Ejemplo n.º 1
0
 def test_file(self):
     """
     An existing file has these attributes
     """
     root = FilePath(self.mktemp())
     root.setContent('the content')
     root.chmod(0777)
     
     stdout, stderr, code = self.runScript(['inspect'], json.dumps({
         'kind': 'file',
         'path': root.path,
     }))
     data = json.loads(stdout)
     
     self.assertEqual(data['kind'], 'file')
     self.assertEqual(data['path'], root.path)
     self.assertEqual(data['exists'], True)
     self.assertEqual(data['filetype'], 'file')
     self.assertEqual(data['owner'], pwd.getpwuid(os.geteuid()).pw_name)
     self.assertEqual(data['group'], grp.getgrgid(os.getegid()).gr_name)
     self.assertEqual(data['perms'], '0777')
     root.restat()
     self.assertEqual(data['ctime'], int(root.statinfo.st_ctime))
     self.assertEqual(type(data['ctime']), int)
     self.assertEqual(data['mtime'], int(root.statinfo.st_mtime))
     self.assertEqual(type(data['mtime']), int)
     self.assertEqual(data['atime'], int(root.statinfo.st_atime))
     self.assertEqual(type(data['atime']), int)
     
     self.assertEqual(data['sha1'], sha1('the content').hexdigest())
     self.assertEqual(data['size'], len('the content'))
Ejemplo n.º 2
0
 def test_directory(self):
     """
     A directory can exist
     """
     root = FilePath(self.mktemp())
     root.makedirs()
     root.chmod(0777)
     
     stdout, stderr, code = self.runScript(['inspect'], json.dumps({
         'kind': 'file',
         'path': root.path,
     }))
     data = json.loads(stdout)
     self.assertEqual(data['kind'], 'file')
     self.assertEqual(data['path'], root.path)
     self.assertEqual(data['exists'], True)
     self.assertEqual(data['filetype'], 'dir')
     self.assertEqual(data['owner'], pwd.getpwuid(os.geteuid()).pw_name)
     self.assertEqual(data['group'], grp.getgrgid(os.getegid()).gr_name)
     self.assertEqual(data['perms'], '0777')
     root.restat()
     self.assertEqual(data['ctime'], int(root.statinfo.st_ctime))
     self.assertEqual(type(data['ctime']), int)
     self.assertEqual(data['mtime'], int(root.statinfo.st_mtime))
     self.assertEqual(type(data['mtime']), int)
     self.assertEqual(data['atime'], int(root.statinfo.st_atime))
     self.assertEqual(type(data['atime']), int)
Ejemplo n.º 3
0
 def test_permissions(self):
     """
     The directory is created with restrictive permissions.
     """
     path = FilePath(self.mktemp())
     DockerPluginScript()._create_listening_directory(path)
     path.restat()
     self.assertEqual(path.getPermissions().shorthand(), "rwx------")
Ejemplo n.º 4
0
 def test_permissions(self):
     """
     The directory is created with restrictive permissions.
     """
     path = FilePath(self.mktemp())
     DockerPluginScript()._create_listening_directory(path)
     path.restat()
     self.assertEqual(path.getPermissions().shorthand(), "rwx------")
Ejemplo n.º 5
0
class ScheduledTask(object):
    """
    Two ScheduledTask instances with same identifier are not permited to run
    concurrently.  There should be no ScheduledTask queue waiting for the lock
    as SchedulerService ticks quite often.
    """
    _time_format = "%Y-%m-%dT%H:%M:%SZ"
    schedule = None
    identifier = None

    def __init__(self,
                 schedule=None,
                 identifier=None,
                 scheduler_directory=None):
        if scheduler_directory is None:
            scheduler_directory = config.scheduler_directory
        if schedule is not None:
            self.schedule = schedule
        if identifier is not None:
            self.identifier = identifier

        assert self.identifier is not None, "self.identifier must be set"
        assert self.schedule is not None, "self.schedule must be set"

        self._last_run = FilePath(scheduler_directory).child(self.identifier)
        self._last_run_lock = FileSystemlockAndMutex(
            FilePath(scheduler_directory).child(self.identifier +
                                                ".lock").path)

    def cancel(self):
        """
        Cancel a currently running task.
        If it is locked, then release the lock.
        """
        if self._last_run_lock.locked:
            self._last_run_lock.release()

    @property
    def should_run(self):
        current_time = datetime.utcnow().replace(tzinfo=tz.tzutc())
        next_cycle = croniter(self.schedule, self.last_run).get_next(datetime)
        if next_cycle <= current_time:
            return True
        return False

    @property
    def last_run(self):
        self._last_run.restat(False)
        if not self._last_run.exists():
            return CANARY_DATE
        with self._last_run.open('r') as in_file:
            date_str = in_file.read()
        return datetime.strptime(date_str,
                                 self._time_format).replace(tzinfo=tz.tzutc())

    def _update_last_run(self, last_run_time):
        """
        Update the time at which this task ran successfully last, by running
        to a file.
        """
        with self._last_run.open('w') as out_file:
            out_file.write(last_run_time.strftime(self._time_format))

    def task(self):
        raise NotImplementedError

    def first_run(self):
        """
        This hook is called if it's the first time a particular scheduled
        operation is run.
        """
        pass

    @defer.inlineCallbacks
    def run(self):
        if self._last_run_lock.locked:
            # do not allow the queue to grow forever
            raise DidNotRun
        yield self._last_run_lock.acquire()
        if not self.should_run:
            self._last_run_lock.release()
            raise DidNotRun
        try:
            if self.last_run == CANARY_DATE:
                log.debug("Detected first run")
                yield defer.maybeDeferred(self.first_run)
            last_run_time = datetime.utcnow()
            yield self.task()
            self._update_last_run(last_run_time)
        except:
            raise
        finally:
            self._last_run_lock.release()
Ejemplo n.º 6
0
class ScheduledTask(object):
    """
    Two ScheduledTask instances with same identifier are not permited to run
    concurrently.  There should be no ScheduledTask queue waiting for the lock
    as SchedulerService ticks quite often.
    """
    _time_format = "%Y-%m-%dT%H:%M:%SZ"
    schedule = None
    identifier = None

    def __init__(self, schedule=None, identifier=None,
                 scheduler_directory=None):
        if scheduler_directory is None:
            scheduler_directory = config.scheduler_directory
        if schedule is not None:
            self.schedule = schedule
        if identifier is not None:
            self.identifier = identifier

        assert self.identifier is not None, "self.identifier must be set"
        assert self.schedule is not None, "self.schedule must be set"

        # XXX: both _last_run_lock and _smear_coef require that there is single
        # instance of the ScheduledTask of each type identified by `identifier`.
        self._last_run = FilePath(scheduler_directory).child(self.identifier)
        self._last_run_lock = FileSystemlockAndMutex(
            FilePath(scheduler_directory).child(self.identifier + ".lock").path
        )
        self._smear_coef = random.random()

    def cancel(self):
        """
        Cancel a currently running task.
        If it is locked, then release the lock.
        """
        if not self._last_run_lock.locked:
            # _last_run_lock.release() will throw if we try to release it
            log.err('BUG: cancelling non-locked task {} without holding lock'.format(self.identifier))
            return
        # probably, cancelling the task TAKEN the lock is even worse :-)
        self._last_run_lock.release()

    @property
    def should_run(self):
        current_time = datetime.utcnow().replace(tzinfo=tz.tzutc())
        next_cycle = croniter(self.schedule, self.last_run).get_next(datetime)
        delta = (croniter(self.schedule, next_cycle).get_next(datetime) - next_cycle).total_seconds()
        next_cycle = next_cycle + timedelta(seconds=delta * 0.1 * self._smear_coef)
        if next_cycle <= current_time:
            return True
        return False


    @property
    def last_run(self):
        self._last_run.restat(False)
        if not self._last_run.exists():
            return CANARY_DATE
        with self._last_run.open('r') as in_file:
            date_str = in_file.read()
        return datetime.strptime(date_str, self._time_format).replace(
            tzinfo=tz.tzutc())

    def _update_last_run(self, last_run_time):
        """
        Update the time at which this task ran successfully last, by running
        to a file.
        """
        with self._last_run.open('w') as out_file:
            out_file.write(last_run_time.strftime(self._time_format))

    def task(self):
        raise NotImplementedError

    def first_run(self):
        """
        This hook is called if it's the first time a particular scheduled
        operation is run.
        """
        pass

    @defer.inlineCallbacks
    def run(self):
        if self._last_run_lock.locked:
            # do not allow the queue to grow forever
            raise DidNotRun
        yield self._last_run_lock.acquire()
        if not self.should_run:
            self._last_run_lock.release()
            raise DidNotRun
        try:
            if self.last_run == CANARY_DATE:
                log.debug("Detected first run")
                yield defer.maybeDeferred(self.first_run)
            last_run_time = datetime.utcnow()
            yield self.task()
            self._update_last_run(last_run_time)
        except:
            raise
        finally:
            self._last_run_lock.release()