def create_with_state(cls, state, repo=None, legacy_mode=False): """ Create a session manager by wrapping existing session state. This method populates the session storage with all of the well known directories (using :meth:`WellKnownDirsHelper.populate()`) :param stage: A pre-existing SessionState object. :param repo: If specified then this particular repository will be used to create the storage for this session. If left out, a new repository is constructed with the default location. :ptype repo: :class:`~plainbox.impl.session.storage.SessionStorageRepository`. :param legacy_mode: Propagated to :meth:`~plainbox.impl.session.storage.SessionStorage.create()` to ensure that legacy (single session) mode is used. :ptype legacy_mode: bool :return: fresh :class:`SessionManager` instance """ logger.debug("SessionManager.create_with_state()") if repo is None: repo = SessionStorageRepository() storage = SessionStorage.create(repo.location, legacy_mode) WellKnownDirsHelper(storage).populate() context = SessionDeviceContext(state) return cls([context], storage)
def get_throwaway_manager(cls, provider_list=None): """ Create a temporary session manager. :param provider_list: (optional) A list of providers to put into the session manager. By default all known providers are added. You can use this argument to customize the behaviour beyond defaults. :returns: A new SessionManager object that will be destroyed when the context manager is left. This method can be used to create a throw-away session manager which is not really meant for running jobs but can be useful to access exporters and other objects stored in providers. """ with tempfile.TemporaryDirectory() as tmp: repo = SessionStorageRepository(tmp) if provider_list is None: provider_list = get_providers() try: manager = cls.create(repo=repo) manager.add_local_device_context() device_context = manager.default_device_context for provider in provider_list: device_context.add_provider(provider) yield manager finally: manager.destroy()
def create_with_unit_list(cls, unit_list=None, repo=None): """ Create a session manager with a fresh session. This method populates the session storage with all of the well known directories (using :meth:`WellKnownDirsHelper.populate()`) :param unit_list: If specified then this will be the initial list of units known by the session state object. :param repo: If specified then this particular repository will be used to create the storage for this session. If left out, a new repository is constructed with the default location. :ptype repo: :class:`~plainbox.impl.session.storage.SessionStorageRepository`. :return: fresh :class:`SessionManager` instance """ logger.debug("SessionManager.create_with_unit_list()") if unit_list is None: unit_list = [] state = SessionState(unit_list) if repo is None: repo = SessionStorageRepository() storage = SessionStorage.create(repo.location) context = SessionDeviceContext(state) WellKnownDirsHelper(storage).populate() return cls([context], storage)
def create(cls, repo=None, legacy_mode=False, prefix='pbox-'): """ Create an empty session manager. This method creates an empty session manager. This is the most generic API that allows applications to freely work with any set of devices. Typically applications will use the :meth:`add_device_context()` method to add additional context objects at a later time. This method creates and populates the session storage with all of the well known directories (using :meth:`WellKnownDirsHelper.populate()`). :param repo: If specified then this particular repository will be used to create the storage for this session. If left out, a new repository is constructed with the default location. :ptype repo: :class:`~plainbox.impl.session.storage.SessionStorageRepository`. :param legacy_mode: Propagated to :meth:`~plainbox.impl.session.storage.SessionStorage.create()` to ensure that legacy (single session) mode is used. :ptype legacy_mode: bool :return: fresh :class:`SessionManager` instance """ logger.debug("SessionManager.create()") if repo is None: repo = SessionStorageRepository() storage = SessionStorage.create(repo.location, legacy_mode, prefix) WellKnownDirsHelper(storage).populate() return cls([], storage)
def test_smoke(self): # Empty directory looks like an empty repository with TemporaryDirectory() as tmp: repo = SessionStorageRepository(tmp) self.assertEqual(repo.location, tmp) self.assertEqual(repo.get_storage_list(), []) self.assertEqual(list(iter(repo)), [])
def get_throwaway_manager(cls, provider_list=None): """ Create a temporary session manager. :param provider_list: (optional) A list of providers to put into the session manager. By default all known providers are added. You can use this argument to customize the behaviour beyond defaults. :returns: A new SessionManager object that will be destroyed when the context manager is left. This method can be used to create a throw-away session manager which is not really meant for running jobs but can be useful to access exporters and other objects stored in providers. """ key = hash(frozenset(provider_list)) if provider_list else '' if not cls._throwaway_managers.get(key): # for safety let's create more persistent tempdir than # the TemporaryDirectory context_manager tmp = tempfile.mkdtemp() atexit.register(lambda: shutil.rmtree(tmp)) repo = SessionStorageRepository(tmp) if provider_list is None: provider_list = get_providers() manager = cls.create(repo=repo) manager.add_local_device_context() device_context = manager.default_device_context cls._throwaway_managers[key] = manager for provider in provider_list: device_context.add_provider(provider) yield cls._throwaway_managers[key]
def _commit_resume(self): logger.debug("_commit_resume()") last_storage = SessionStorageRepository().get_last_storage() assert last_storage is not None, "no saved session to resume" self._manager = SessionManager.load_session(self.job_list, last_storage, lambda session: self) logger.debug("_commit_resume() finished")
def previous_session_file(self): """ Check the filesystem for previous session data Returns the full pathname to the session file if it exists """ last_storage = SessionStorageRepository().get_last_storage() if last_storage and os.path.exists(last_storage.session_file): return last_storage.session_file
def test_get_last_storage__broken_symlink(self): # Directory with some sub-directories looks like a repository # with a bunch of sessions inside. with TemporaryDirectory() as tmp: # Create a repository without any sessions and one broken symlink repo = SessionStorageRepository(tmp) self._populate_dummy_repo(repo, [], "b0rken.session") # Get the last storage object storage = repo.get_last_storage() # Make sure it's not valid self.assertEqual(storage, None)
def test_get_last_storage(self): # Directory with some sub-directories looks like a repository # with a bunch of sessions inside. with TemporaryDirectory() as tmp: # Create a repository and some dummy data repo = SessionStorageRepository(tmp) self._populate_dummy_repo(repo) # Get the last storage object storage = repo.get_last_storage() # Check that we got session1 self.assertEqual(os.path.basename(storage.location), 'session1')
def test_get_storage_list(self): # Directory with some sub-directories looks like a repository # with a bunch of sessions inside. with TemporaryDirectory() as tmp: # Create a repository and some dummy data repo = SessionStorageRepository(tmp) self._populate_dummy_repo(repo) # Get a list of storage objects storage_list = repo.get_storage_list() # Check if we got our data right. # The results are not sorted so we sort them for testing storage_name_list = [ os.path.basename(storage.location) for storage in storage_list] self.assertEqual( sorted(storage_name_list), ["s1.session", "s2.session"])
def create_session(cls, job_list=None, repo=None, legacy_mode=False): """ Create a session manager with a fresh session. This method populates the session storage with all of the well known directories (using :meth:`WellKnownDirsHelper.populate()`) :param job_list: If specified then this will be the initial list of jobs known by the session state object. This can be specified for convenience but is really optional since the application can always add more jobs to an existing session. :ptype job_list: list of :class:`~plainbox.abc.IJobDefinition`. :param repo: If specified then this particular repository will be used to create the storage for this session. If left out, a new repository is constructed with the default location. :ptype repo: :class:`~plainbox.impl.session.storage.SessionStorageRepository`. :param legacy_mode: Propagated to :meth:`~plainbox.impl.session.storage.SessionStorage.create()` to ensure that legacy (single session) mode is used. :ptype legacy_mode: bool :return: fresh :class:`SessionManager` instance """ logger.debug("SessionManager.create_session()") if job_list is None: job_list = [] state = SessionState(job_list) if repo is None: repo = SessionStorageRepository() storage = SessionStorage.create(repo.location, legacy_mode) WellKnownDirsHelper(storage).populate() return cls(state, storage)