vortex-nwp 2.1.2__tar.gz → 2.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/PKG-INFO +1 -1
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/pyproject.toml +1 -1
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/__init__.py +2 -2
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/data/abstractstores.py +43 -39
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/data/geometries.py +31 -1
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/data/handlers.py +1 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/data/providers.py +8 -3
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/data/stores.py +44 -41
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/sessions.py +3 -2
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/storage.py +12 -10
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex_nwp.egg-info/PKG-INFO +1 -1
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex_nwp.egg-info/SOURCES.txt +2 -0
- vortex_nwp-2.2.0/tests/test_geometries.py +153 -0
- vortex_nwp-2.2.0/tests/test_user_remote_dtree.py +91 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/LICENSE +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/README.md +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/setup.cfg +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/algo/__init__.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/algo/components.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/algo/mpitools.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/algo/mpitools_templates/__init__.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/algo/mpitools_templates/envelope_wrapper_default.tpl +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/algo/mpitools_templates/envelope_wrapper_mpiauto.tpl +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/algo/mpitools_templates/wrapstd_wrapper_default.tpl +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/algo/serversynctools.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/config.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/data/__init__.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/data/containers.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/data/contents.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/data/executables.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/data/flow.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/data/geometries.ini +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/data/outflow.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/data/resources.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/data/sync_templates/__init__.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/gloves.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/layout/__init__.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/layout/contexts.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/layout/dataflow.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/layout/monitor.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/__init__.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/__init__.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/assim.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/clim.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/coupling.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/eda.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/eps.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/forecasts.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/fpserver.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/ifsnaming.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/ifsroot.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/monitoring.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/mpitools.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/odbtools.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/oopsroot.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/oopstests.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/request.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/algo/stdpost.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/__init__.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/assim.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/boundaries.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/climfiles.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/configfiles.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/consts.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/ctpini.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/diagnostics.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/eda.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/eps.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/executables.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/fields.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/gridfiles.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/logs.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/modelstates.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/monitoring.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/namelists.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/obs.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/oopsexec.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/providers.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/query.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/stores.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/data/surfex.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/syntax/__init__.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/syntax/stdattrs.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/__init__.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/addons.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/agt.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/bdap.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/bdcp.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/bdm.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/bdmp.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/conftools.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/drhook.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/grib.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/gribdiff.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/ifstools.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/igastuff.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/mars.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/odb.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/partitioning.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/tools/satrad.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/util/__init__.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/util/async.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/util/beacon.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/util/diffpygram.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/util/ens.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/util/hooks.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/util/taskdeco.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/util/usepygram.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/nwp/util/usetnt.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/proxy.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/syntax/__init__.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/syntax/stdattrs.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/syntax/stddeco.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/toolbox.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/__init__.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/actions.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/addons.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/arm.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/compression.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/date.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/ddhpack.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/delayedactions.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/env.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/folder.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/grib.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/lfi.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/listings.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/names.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/net.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/odb.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/parallelism.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/prestaging.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/rawfiles.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/schedulers.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/services.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/surfex.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/systems.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/tools/targets.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/util/__init__.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/util/config.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/util/empty.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/util/helpers.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/util/introspection.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/util/iosponge.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/util/roles.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/util/storefunctions.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/util/structs.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex/util/worker.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex_nwp.egg-info/dependency_links.txt +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex_nwp.egg-info/requires.txt +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/src/vortex_nwp.egg-info/top_level.txt +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_algo_server.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_arpifs_listings_integration.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_cfgparser.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_cfgtemplating.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_compression.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_config.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_conftools.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_containers.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_doctests.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_ecflow.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_ecmwf_interface.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_env.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_epygram.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_gco.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_ifstools.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_import.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_iosponge.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_job_examples.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_layoutappconf.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_layoutjobs.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_layoutmonitor.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_layoutnodes.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_net_netstat.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_net_ssh.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_partitioning.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_providers.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_sessions_stuff.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_simpleworkflow.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_smartftget.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_ssh.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_storage.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_stores.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_syntax.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_targets.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_templates.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_toolsodb.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_uget.py +0 -0
- {vortex_nwp-2.1.2 → vortex_nwp-2.2.0}/tests/test_vortexnames.py +0 -0
|
@@ -53,10 +53,10 @@ from .toolbox import algo as task
|
|
|
53
53
|
|
|
54
54
|
from . import nwp as nwp # footprints import
|
|
55
55
|
|
|
56
|
-
__version__ = "2.
|
|
56
|
+
__version__ = "2.2.0"
|
|
57
57
|
__prompt__ = "Vortex v-" + __version__ + ":"
|
|
58
58
|
|
|
59
|
-
__nextversion__ = "2.1
|
|
59
|
+
__nextversion__ = "2.2.1"
|
|
60
60
|
__tocinfoline__ = "VORTEX core package"
|
|
61
61
|
|
|
62
62
|
__all__ = [
|
|
@@ -14,7 +14,12 @@ from bronx.system import hash as hashutils
|
|
|
14
14
|
import footprints
|
|
15
15
|
|
|
16
16
|
from vortex import sessions
|
|
17
|
-
from vortex.config import
|
|
17
|
+
from vortex.config import (
|
|
18
|
+
from_config,
|
|
19
|
+
ConfigurationError,
|
|
20
|
+
is_defined,
|
|
21
|
+
get_from_config_w_default,
|
|
22
|
+
)
|
|
18
23
|
from vortex.syntax.stdattrs import (
|
|
19
24
|
hashalgo,
|
|
20
25
|
hashalgo_avail_list,
|
|
@@ -438,6 +443,7 @@ class MultiStore(footprints.FootprintBase):
|
|
|
438
443
|
attr=dict(
|
|
439
444
|
scheme=dict(alias=("protocol",)),
|
|
440
445
|
netloc=dict(type=Namespace, alias=("domain", "namespace")),
|
|
446
|
+
username=dict(type=str),
|
|
441
447
|
refillstore=dict(
|
|
442
448
|
type=bool,
|
|
443
449
|
optional=True,
|
|
@@ -792,6 +798,9 @@ class ArchiveStore(Store):
|
|
|
792
798
|
netloc=dict(
|
|
793
799
|
values=["open.archive.fr"],
|
|
794
800
|
),
|
|
801
|
+
username=dict(
|
|
802
|
+
type=str,
|
|
803
|
+
),
|
|
795
804
|
storehash=dict(
|
|
796
805
|
values=hashalgo_avail_list,
|
|
797
806
|
),
|
|
@@ -843,6 +852,13 @@ class ArchiveStore(Store):
|
|
|
843
852
|
def underlying_archive_kind(self):
|
|
844
853
|
return "std"
|
|
845
854
|
|
|
855
|
+
@property
|
|
856
|
+
def archive_entry(self):
|
|
857
|
+
pattern = get_from_config_w_default(
|
|
858
|
+
section="storage", key="rootdir", default="~/vortex"
|
|
859
|
+
)
|
|
860
|
+
return pattern.replace("%usr%", self.username)
|
|
861
|
+
|
|
846
862
|
@property
|
|
847
863
|
def actual_storage(self):
|
|
848
864
|
"""This archive network name (potentially read form the configuration file)."""
|
|
@@ -894,6 +910,7 @@ class ArchiveStore(Store):
|
|
|
894
910
|
storage=self.actual_storage,
|
|
895
911
|
tube=self.actual_storetube,
|
|
896
912
|
readonly=self.readonly,
|
|
913
|
+
entry=self.archive_entry,
|
|
897
914
|
)
|
|
898
915
|
self._archives_object_stack.add(self._archive)
|
|
899
916
|
return self._archive
|
|
@@ -909,25 +926,12 @@ class ArchiveStore(Store):
|
|
|
909
926
|
|
|
910
927
|
archive = property(_get_archive, _set_archive, _del_archive)
|
|
911
928
|
|
|
912
|
-
def _inarchiveformatpath(self, remote):
|
|
913
|
-
# Remove extra slashes
|
|
914
|
-
formatted = remote["path"].lstrip(self.system.path.sep)
|
|
915
|
-
# Store head ?
|
|
916
|
-
if self.storehead:
|
|
917
|
-
formatted = self.system.path.join(self.storehead, formatted)
|
|
918
|
-
# Store root (if specified)
|
|
919
|
-
pathroot = remote.get("root", self.storeroot)
|
|
920
|
-
if pathroot is not None:
|
|
921
|
-
formatted = self.system.path.join(pathroot, formatted)
|
|
922
|
-
return formatted
|
|
923
|
-
|
|
924
929
|
def inarchivecheck(self, remote, options):
|
|
925
930
|
"""Use the archive object to check if **remote** exists."""
|
|
926
931
|
# Try to delete the md5 file but ignore errors...
|
|
927
932
|
if self._hash_check_or_delete(self.inarchivecheck, remote, options):
|
|
928
933
|
return self.archive.check(
|
|
929
|
-
|
|
930
|
-
username=remote.get("username", None),
|
|
934
|
+
remote["path"],
|
|
931
935
|
fmt=options.get("fmt", "foo"),
|
|
932
936
|
compressionpipeline=self._actual_cpipeline,
|
|
933
937
|
)
|
|
@@ -937,8 +941,7 @@ class ArchiveStore(Store):
|
|
|
937
941
|
def inarchivelocate(self, remote, options):
|
|
938
942
|
"""Use the archive object to obtain **remote** physical location."""
|
|
939
943
|
return self.archive.fullpath(
|
|
940
|
-
|
|
941
|
-
username=remote.get("username", None),
|
|
944
|
+
remote["path"],
|
|
942
945
|
fmt=options.get("fmt", "foo"),
|
|
943
946
|
compressionpipeline=self._actual_cpipeline,
|
|
944
947
|
)
|
|
@@ -946,15 +949,13 @@ class ArchiveStore(Store):
|
|
|
946
949
|
def inarchivelist(self, remote, options):
|
|
947
950
|
"""Use the archive object to list available files."""
|
|
948
951
|
return self.archive.list(
|
|
949
|
-
|
|
950
|
-
username=remote.get("username", None),
|
|
952
|
+
remote["path"],
|
|
951
953
|
)
|
|
952
954
|
|
|
953
955
|
def inarchiveprestageinfo(self, remote, options):
|
|
954
956
|
"""Returns the prestaging informations"""
|
|
955
957
|
return self.archive.prestageinfo(
|
|
956
|
-
|
|
957
|
-
username=remote.get("username", None),
|
|
958
|
+
remote["path"],
|
|
958
959
|
fmt=options.get("fmt", "foo"),
|
|
959
960
|
compressionpipeline=self._actual_cpipeline,
|
|
960
961
|
)
|
|
@@ -965,16 +966,15 @@ class ArchiveStore(Store):
|
|
|
965
966
|
"inarchiveget on %s://%s/%s (to: %s)",
|
|
966
967
|
self.scheme,
|
|
967
968
|
self.netloc,
|
|
968
|
-
|
|
969
|
+
remote["path"],
|
|
969
970
|
local,
|
|
970
971
|
)
|
|
971
972
|
rc = self.archive.retrieve(
|
|
972
|
-
|
|
973
|
+
remote["path"],
|
|
973
974
|
local,
|
|
974
975
|
intent=options.get("intent", ARCHIVE_GET_INTENT_DEFAULT),
|
|
975
976
|
fmt=options.get("fmt", "foo"),
|
|
976
977
|
info=options.get("rhandler", None),
|
|
977
|
-
username=remote["username"],
|
|
978
978
|
compressionpipeline=self._actual_cpipeline,
|
|
979
979
|
)
|
|
980
980
|
return rc and self._hash_get_check(
|
|
@@ -987,16 +987,15 @@ class ArchiveStore(Store):
|
|
|
987
987
|
"inarchiveearlyget on %s://%s/%s (to: %s)",
|
|
988
988
|
self.scheme,
|
|
989
989
|
self.netloc,
|
|
990
|
-
|
|
990
|
+
remote["path"],
|
|
991
991
|
local,
|
|
992
992
|
)
|
|
993
993
|
rc = self.archive.earlyretrieve(
|
|
994
|
-
|
|
994
|
+
remote["path"],
|
|
995
995
|
local,
|
|
996
996
|
intent=options.get("intent", ARCHIVE_GET_INTENT_DEFAULT),
|
|
997
997
|
fmt=options.get("fmt", "foo"),
|
|
998
998
|
info=options.get("rhandler", None),
|
|
999
|
-
username=remote["username"],
|
|
1000
999
|
compressionpipeline=self._actual_cpipeline,
|
|
1001
1000
|
)
|
|
1002
1001
|
return rc
|
|
@@ -1007,17 +1006,16 @@ class ArchiveStore(Store):
|
|
|
1007
1006
|
"inarchivefinaliseget on %s://%s/%s (to: %s)",
|
|
1008
1007
|
self.scheme,
|
|
1009
1008
|
self.netloc,
|
|
1010
|
-
|
|
1009
|
+
remote["path"],
|
|
1011
1010
|
local,
|
|
1012
1011
|
)
|
|
1013
1012
|
rc = self.archive.finaliseretrieve(
|
|
1014
1013
|
result_id,
|
|
1015
|
-
|
|
1014
|
+
remote["path"],
|
|
1016
1015
|
local,
|
|
1017
1016
|
intent=options.get("intent", ARCHIVE_GET_INTENT_DEFAULT),
|
|
1018
1017
|
fmt=options.get("fmt", "foo"),
|
|
1019
1018
|
info=options.get("rhandler", None),
|
|
1020
|
-
username=remote["username"],
|
|
1021
1019
|
compressionpipeline=self._actual_cpipeline,
|
|
1022
1020
|
)
|
|
1023
1021
|
return rc and self._hash_get_check(
|
|
@@ -1030,16 +1028,15 @@ class ArchiveStore(Store):
|
|
|
1030
1028
|
"inarchiveput to %s://%s/%s (from: %s)",
|
|
1031
1029
|
self.scheme,
|
|
1032
1030
|
self.netloc,
|
|
1033
|
-
|
|
1031
|
+
remote["path"],
|
|
1034
1032
|
local,
|
|
1035
1033
|
)
|
|
1036
1034
|
rc = self.archive.insert(
|
|
1037
|
-
|
|
1035
|
+
remote["path"],
|
|
1038
1036
|
local,
|
|
1039
1037
|
intent=ARCHIVE_PUT_INTENT,
|
|
1040
1038
|
fmt=options.get("fmt", "foo"),
|
|
1041
1039
|
info=options.get("rhandler"),
|
|
1042
|
-
username=remote["username"],
|
|
1043
1040
|
compressionpipeline=self._actual_cpipeline,
|
|
1044
1041
|
enforcesync=options.get("enforcesync", False),
|
|
1045
1042
|
usejeeves=options.get("delayed", None),
|
|
@@ -1051,15 +1048,14 @@ class ArchiveStore(Store):
|
|
|
1051
1048
|
"inarchivedelete on %s://%s/%s",
|
|
1052
1049
|
self.scheme,
|
|
1053
1050
|
self.netloc,
|
|
1054
|
-
|
|
1051
|
+
remote["path"],
|
|
1055
1052
|
)
|
|
1056
1053
|
# Try to delete the md5 file but ignore errors...
|
|
1057
1054
|
self._hash_check_or_delete(self.inarchivedelete, remote, options)
|
|
1058
1055
|
return self.archive.delete(
|
|
1059
|
-
|
|
1056
|
+
remote["path"],
|
|
1060
1057
|
fmt=options.get("fmt", "foo"),
|
|
1061
1058
|
info=options.get("rhandler", None),
|
|
1062
|
-
username=remote["username"],
|
|
1063
1059
|
compressionpipeline=self._actual_cpipeline,
|
|
1064
1060
|
)
|
|
1065
1061
|
|
|
@@ -1081,6 +1077,9 @@ class CacheStore(Store):
|
|
|
1081
1077
|
netloc=dict(
|
|
1082
1078
|
values=["open.cache.fr"],
|
|
1083
1079
|
),
|
|
1080
|
+
username=dict(
|
|
1081
|
+
type=str,
|
|
1082
|
+
),
|
|
1084
1083
|
storehash=dict(
|
|
1085
1084
|
values=hashalgo_avail_list,
|
|
1086
1085
|
),
|
|
@@ -1130,7 +1129,7 @@ class CacheStore(Store):
|
|
|
1130
1129
|
def _get_cache(self):
|
|
1131
1130
|
if not self._cache:
|
|
1132
1131
|
self._cache = footprints.proxy.caches.default(
|
|
1133
|
-
entry=self.
|
|
1132
|
+
entry=self.cache_entry,
|
|
1134
1133
|
rtouch=self.rtouch,
|
|
1135
1134
|
rtouchskip=self.rtouchskip,
|
|
1136
1135
|
readonly=self.readonly,
|
|
@@ -1255,6 +1254,7 @@ class PromiseStore(footprints.FootprintBase):
|
|
|
1255
1254
|
attr=dict(
|
|
1256
1255
|
scheme=dict(alias=("protocol",)),
|
|
1257
1256
|
netloc=dict(type=Namespace, alias=("domain", "namespace")),
|
|
1257
|
+
username=dict(type=str),
|
|
1258
1258
|
storetrack=dict(
|
|
1259
1259
|
type=bool,
|
|
1260
1260
|
default=True,
|
|
@@ -1282,12 +1282,14 @@ class PromiseStore(footprints.FootprintBase):
|
|
|
1282
1282
|
scheme=self.proxyscheme,
|
|
1283
1283
|
netloc=self.prstorename,
|
|
1284
1284
|
storetrack=self.storetrack,
|
|
1285
|
+
username=self.username,
|
|
1285
1286
|
)
|
|
1286
1287
|
if self.promise is None:
|
|
1287
1288
|
logger.critical(
|
|
1288
|
-
"Could not find store scheme <%s> netloc <%s>",
|
|
1289
|
+
"Could not find store scheme <%s> netloc <%s> username <%s>",
|
|
1289
1290
|
self.proxyscheme,
|
|
1290
1291
|
self.prstorename,
|
|
1292
|
+
self.username,
|
|
1291
1293
|
)
|
|
1292
1294
|
raise ValueError("Could not get a Promise Store")
|
|
1293
1295
|
|
|
@@ -1296,12 +1298,14 @@ class PromiseStore(footprints.FootprintBase):
|
|
|
1296
1298
|
scheme=self.proxyscheme,
|
|
1297
1299
|
netloc=self.netloc,
|
|
1298
1300
|
storetrack=self.storetrack,
|
|
1301
|
+
username=self.username,
|
|
1299
1302
|
)
|
|
1300
1303
|
if self.other is None:
|
|
1301
1304
|
logger.critical(
|
|
1302
|
-
"Could not find store scheme <%s> netloc <%s>",
|
|
1305
|
+
"Could not find store scheme <%s> netloc <%s> username <%s>",
|
|
1303
1306
|
self.proxyscheme,
|
|
1304
1307
|
self.netloc,
|
|
1308
|
+
self.username,
|
|
1305
1309
|
)
|
|
1306
1310
|
raise ValueError("Could not get an Other Store")
|
|
1307
1311
|
|
|
@@ -759,17 +759,47 @@ hgeometry_deco = footprints.DecorativeFootprint(
|
|
|
759
759
|
# Load default geometries when the module is first imported
|
|
760
760
|
|
|
761
761
|
|
|
762
|
-
def
|
|
762
|
+
def _get_user_config_dir():
|
|
763
|
+
"""Get the user's vortex configuration directory.
|
|
764
|
+
|
|
765
|
+
This function is separated out to make it easier to mock in tests.
|
|
766
|
+
"""
|
|
767
|
+
from pathlib import Path
|
|
768
|
+
from vortex.tools.env import Environment
|
|
769
|
+
|
|
770
|
+
env = Environment(active=False)
|
|
771
|
+
return Path(env.HOME) / ".vortexrc"
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
def load(
|
|
775
|
+
inifile="@geometries.ini",
|
|
776
|
+
refresh=False,
|
|
777
|
+
verbose=True,
|
|
778
|
+
_user_config_dir=None,
|
|
779
|
+
):
|
|
763
780
|
"""Load a set of pre-defined geometries from a configuration file.
|
|
764
781
|
|
|
765
782
|
The class that will be instantiated depends on the "kind" keyword..
|
|
783
|
+
|
|
784
|
+
:param _user_config_dir: Override user config directory (for testing)
|
|
766
785
|
"""
|
|
767
786
|
iniconf = configparser.ConfigParser()
|
|
787
|
+
|
|
788
|
+
# Load from vortex distribution
|
|
768
789
|
with importlib.resources.open_text(
|
|
769
790
|
"vortex.data",
|
|
770
791
|
"geometries.ini",
|
|
771
792
|
) as fh:
|
|
772
793
|
iniconf.read_file(fh)
|
|
794
|
+
|
|
795
|
+
# Load from user's config directory if it exists
|
|
796
|
+
if _user_config_dir is None:
|
|
797
|
+
_user_config_dir = _get_user_config_dir()
|
|
798
|
+
user_geometries = _user_config_dir / "geometries.ini"
|
|
799
|
+
if user_geometries.exists():
|
|
800
|
+
with open(user_geometries, encoding="utf-8") as fh:
|
|
801
|
+
iniconf.read_file(fh)
|
|
802
|
+
|
|
773
803
|
for item in iniconf.sections():
|
|
774
804
|
gdesc = dict(iniconf.items(item))
|
|
775
805
|
gkind = gdesc.get("kind")
|
|
@@ -14,6 +14,7 @@ from bronx.fancies import loggers
|
|
|
14
14
|
import footprints
|
|
15
15
|
from footprints import proxy as fpx
|
|
16
16
|
|
|
17
|
+
import vortex
|
|
17
18
|
from vortex import config
|
|
18
19
|
from vortex.syntax.stdattrs import (
|
|
19
20
|
xpid,
|
|
@@ -56,6 +57,7 @@ class Provider(footprints.FootprintBase):
|
|
|
56
57
|
info="The username that will be used whenever necessary.",
|
|
57
58
|
optional=True,
|
|
58
59
|
default=None,
|
|
60
|
+
access="rwx",
|
|
59
61
|
alias=("user", "logname"),
|
|
60
62
|
),
|
|
61
63
|
),
|
|
@@ -66,6 +68,9 @@ class Provider(footprints.FootprintBase):
|
|
|
66
68
|
logger.debug("Abstract provider init %s", self.__class__)
|
|
67
69
|
super().__init__(*args, **kw)
|
|
68
70
|
|
|
71
|
+
if not self.username:
|
|
72
|
+
self.username = vortex.ticket().glove.user
|
|
73
|
+
|
|
69
74
|
def _str_more(self):
|
|
70
75
|
"""Additional information to print representation."""
|
|
71
76
|
try:
|
|
@@ -279,7 +284,7 @@ class Vortex(Provider):
|
|
|
279
284
|
|
|
280
285
|
_DEFAULT_NAME_BUILDER = names.VortexNameBuilder()
|
|
281
286
|
_CUSTOM_NAME_BUILDERS = dict()
|
|
282
|
-
_SPECIAL_EXPS = ("
|
|
287
|
+
_SPECIAL_EXPS = ("OPER", "DBLE", "TEST", "MIRR")
|
|
283
288
|
|
|
284
289
|
_footprint = [
|
|
285
290
|
block,
|
|
@@ -366,8 +371,8 @@ class Vortex(Provider):
|
|
|
366
371
|
self._namebuilder = self._CUSTOM_NAME_BUILDERS[self.namebuild]
|
|
367
372
|
else:
|
|
368
373
|
self._namebuilder = self._DEFAULT_NAME_BUILDER
|
|
369
|
-
if self.experiment in (n.
|
|
370
|
-
self.experiment = self.experiment.
|
|
374
|
+
if self.experiment in (n.lower() for n in self._SPECIAL_EXPS):
|
|
375
|
+
self.experiment = self.experiment.upper()
|
|
371
376
|
|
|
372
377
|
# Ensure compatibility with deprecated namespace attribute
|
|
373
378
|
# Under the hood the namespace attribute is still used to
|
|
@@ -741,19 +741,6 @@ class VortexStdBaseArchiveStore(_VortexBaseArchiveStore):
|
|
|
741
741
|
def remap_read(self, remote, options):
|
|
742
742
|
"""Reformulates the remote path to compatible vortex namespace."""
|
|
743
743
|
remote = copy.copy(remote)
|
|
744
|
-
try:
|
|
745
|
-
remote["root"] = config.from_config(
|
|
746
|
-
section="storage",
|
|
747
|
-
key="rootdir",
|
|
748
|
-
)
|
|
749
|
-
except config.ConfigurationError as e:
|
|
750
|
-
msg = (
|
|
751
|
-
"Trying to write to archive but location is not configured. "
|
|
752
|
-
'Make sure key "rootdir" is defined in storage section of '
|
|
753
|
-
"the configuration.\n"
|
|
754
|
-
"See https://vortex-nwp.readthedocs.io/en/latest/user-guide/configuration.html#storage"
|
|
755
|
-
)
|
|
756
|
-
raise config.ConfigurationError(msg) from e
|
|
757
744
|
return remote
|
|
758
745
|
|
|
759
746
|
remap_write = remap_read
|
|
@@ -801,22 +788,13 @@ class VortexOpBaseArchiveStore(_VortexBaseArchiveStore):
|
|
|
801
788
|
),
|
|
802
789
|
)
|
|
803
790
|
|
|
791
|
+
@property
|
|
792
|
+
def archive_entry(self):
|
|
793
|
+
return config.from_config(section="storage", key="op_rootdir")
|
|
794
|
+
|
|
804
795
|
def remap_read(self, remote, options):
|
|
805
796
|
"""Reformulates the remote path to compatible vortex namespace."""
|
|
806
797
|
remote = copy.copy(remote)
|
|
807
|
-
try:
|
|
808
|
-
remote["root"] = config.from_config(
|
|
809
|
-
section="storage",
|
|
810
|
-
key="op_rootdir",
|
|
811
|
-
)
|
|
812
|
-
except config.ConfigurationError as e:
|
|
813
|
-
msg = (
|
|
814
|
-
"Trying to write to operational data archive but location"
|
|
815
|
-
' is not configured. Make sure key "op_rootdir" is defined in '
|
|
816
|
-
"the storage section of the configuration.\n"
|
|
817
|
-
"See https://vortex-nwp.readthedocs.io/en/latest/user-guide/configuration.html#storage"
|
|
818
|
-
)
|
|
819
|
-
raise config.ConfigurationError(msg) from e
|
|
820
798
|
xpath = remote["path"].split("/")
|
|
821
799
|
if len(xpath) >= 5 and re.match(r"^\d{8}T\d{2,4}", xpath[4]):
|
|
822
800
|
# If a date is detected
|
|
@@ -915,7 +893,11 @@ class VortexArchiveStore(MultiStore):
|
|
|
915
893
|
|
|
916
894
|
def alternates_fpextras(self):
|
|
917
895
|
"""Deal with some ArchiveStores' specific attributes."""
|
|
918
|
-
return dict(
|
|
896
|
+
return dict(
|
|
897
|
+
username=self.username,
|
|
898
|
+
storehead=self.storehead,
|
|
899
|
+
storesync=self.storesync,
|
|
900
|
+
)
|
|
919
901
|
|
|
920
902
|
|
|
921
903
|
class _VortexCacheBaseStore(CacheStore, _VortexStackedStorageMixin):
|
|
@@ -993,9 +975,20 @@ class VortexCacheMtStore(_VortexCacheBaseStore):
|
|
|
993
975
|
),
|
|
994
976
|
)
|
|
995
977
|
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
978
|
+
@property
|
|
979
|
+
def cache_entry(self):
|
|
980
|
+
try:
|
|
981
|
+
cacheloc = config.from_config(
|
|
982
|
+
section="data-tree",
|
|
983
|
+
key="rootdir",
|
|
984
|
+
)
|
|
985
|
+
except config.ConfigurationError:
|
|
986
|
+
cacheloc = os.path.join(os.environ["HOME"], ".vortex.d")
|
|
987
|
+
|
|
988
|
+
if self.username != self.system.glove.user:
|
|
989
|
+
return os.path.join(cacheloc, self.username)
|
|
990
|
+
|
|
991
|
+
return cacheloc
|
|
999
992
|
|
|
1000
993
|
|
|
1001
994
|
class VortexCacheOp2ResearchStore(_VortexCacheBaseStore):
|
|
@@ -1016,19 +1009,17 @@ class VortexCacheOp2ResearchStore(_VortexCacheBaseStore):
|
|
|
1016
1009
|
),
|
|
1017
1010
|
)
|
|
1018
1011
|
|
|
1019
|
-
|
|
1020
|
-
|
|
1012
|
+
@property
|
|
1013
|
+
def cache_entry(self):
|
|
1021
1014
|
if not config.is_defined(section="data-tree", key="op_rootdir"):
|
|
1022
|
-
|
|
1015
|
+
msg = (
|
|
1023
1016
|
"Using special experiment but corresponding cache location "
|
|
1024
1017
|
'is not configured. Bet sure to set "op_rootdir" in configuration. '
|
|
1025
1018
|
"See https://vortex-nwp.readthedocs.io/en/latest/user-guide/oper-dble-data-trees"
|
|
1026
1019
|
)
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
)
|
|
1031
|
-
self.location = os.path.join(cachepath, "vortex")
|
|
1020
|
+
raise config.ConfigurationError(msg)
|
|
1021
|
+
|
|
1022
|
+
return config.from_config(section="data-tree", key="op_rootdir")
|
|
1032
1023
|
|
|
1033
1024
|
|
|
1034
1025
|
class _AbstractVortexCacheMultiStore(MultiStore):
|
|
@@ -1103,6 +1094,9 @@ class VortexCacheStore(_AbstractVortexCacheMultiStore):
|
|
|
1103
1094
|
f"{self.netloc.firstname}.stacked-cache-mt.fr",
|
|
1104
1095
|
]
|
|
1105
1096
|
|
|
1097
|
+
def alternates_fpextras(self):
|
|
1098
|
+
return dict(username=self.username)
|
|
1099
|
+
|
|
1106
1100
|
|
|
1107
1101
|
class VortexVsopCacheStore(_AbstractVortexCacheMultiStore):
|
|
1108
1102
|
"""The go to store for data cached by VORTEX operational experiments.
|
|
@@ -1145,6 +1139,9 @@ class VortexVsopCacheStore(_AbstractVortexCacheMultiStore):
|
|
|
1145
1139
|
]
|
|
1146
1140
|
return todo
|
|
1147
1141
|
|
|
1142
|
+
def alternates_fpextras(self):
|
|
1143
|
+
return dict(username=self.username)
|
|
1144
|
+
|
|
1148
1145
|
|
|
1149
1146
|
class _AbstractVortexStackMultiStore(MultiStore):
|
|
1150
1147
|
"""Any Cache based Vortex multi store."""
|
|
@@ -1267,6 +1264,9 @@ class VortexStoreLegacy(MultiStore):
|
|
|
1267
1264
|
for d in (".cache.fr", ".archive-legacy.fr")
|
|
1268
1265
|
]
|
|
1269
1266
|
|
|
1267
|
+
def alternates_fpextras(self):
|
|
1268
|
+
return dict(username=self.username)
|
|
1269
|
+
|
|
1270
1270
|
|
|
1271
1271
|
class VortexStore(MultiStore):
|
|
1272
1272
|
"""Combined cache and archive VORTEX stores.
|
|
@@ -1315,6 +1315,9 @@ class VortexStore(MultiStore):
|
|
|
1315
1315
|
)
|
|
1316
1316
|
]
|
|
1317
1317
|
|
|
1318
|
+
def alternates_fpextras(self):
|
|
1319
|
+
return dict(username=self.username)
|
|
1320
|
+
|
|
1318
1321
|
|
|
1319
1322
|
class PromiseCacheStore(VortexCacheMtStore):
|
|
1320
1323
|
"""Some kind of vortex cache for EXPECTED resources."""
|
|
@@ -1332,9 +1335,9 @@ class PromiseCacheStore(VortexCacheMtStore):
|
|
|
1332
1335
|
),
|
|
1333
1336
|
)
|
|
1334
1337
|
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
+
@property
|
|
1339
|
+
def cache_promise(self):
|
|
1340
|
+
return os.path.join(super().cache_entry, "promise")
|
|
1338
1341
|
|
|
1339
1342
|
@staticmethod
|
|
1340
1343
|
def _add_default_options(options):
|
|
@@ -85,8 +85,9 @@ def exit():
|
|
|
85
85
|
"""Ask all inactive sessions to close, then close the active one."""
|
|
86
86
|
tags = keys()
|
|
87
87
|
xtag = Ticket.tag_focus()
|
|
88
|
-
tags
|
|
89
|
-
|
|
88
|
+
if xtag in tags:
|
|
89
|
+
tags.remove(xtag)
|
|
90
|
+
tags.append(xtag)
|
|
90
91
|
ok = True
|
|
91
92
|
for s in [get(tag=x) for x in tags]:
|
|
92
93
|
ok = s.exit() and ok
|
|
@@ -548,6 +548,11 @@ class AbstractArchive(Storage):
|
|
|
548
548
|
tube=dict(
|
|
549
549
|
info="How to communicate with the archive ?",
|
|
550
550
|
),
|
|
551
|
+
entry=dict(
|
|
552
|
+
optional=False,
|
|
553
|
+
type=str,
|
|
554
|
+
info="The absolute path to the archive space",
|
|
555
|
+
),
|
|
551
556
|
),
|
|
552
557
|
)
|
|
553
558
|
|
|
@@ -560,23 +565,20 @@ class AbstractArchive(Storage):
|
|
|
560
565
|
def realkind(self):
|
|
561
566
|
return "archive"
|
|
562
567
|
|
|
563
|
-
def _formatted_path(self,
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
rawpath = self.sh.path.join(root, rawpath.lstrip("/"))
|
|
568
|
+
def _formatted_path(self, subpath, **kwargs):
|
|
569
|
+
path = self.sh.path.join(self.entry, subpath.lstrip("/"))
|
|
570
|
+
|
|
567
571
|
# Deal with compression
|
|
568
572
|
compressionpipeline = kwargs.get("compressionpipeline", None)
|
|
569
573
|
if compressionpipeline is not None:
|
|
570
|
-
|
|
571
|
-
return self.sh.anyft_remote_rewrite(
|
|
572
|
-
rawpath, fmt=kwargs.get("fmt", "foo")
|
|
573
|
-
)
|
|
574
|
+
path += compressionpipeline.suffix
|
|
575
|
+
return self.sh.anyft_remote_rewrite(path, fmt=kwargs.get("fmt", "foo"))
|
|
574
576
|
|
|
575
577
|
def _actual_proxy_method(self, pmethod):
|
|
576
578
|
"""Create a proxy method based on the **pmethod** actual method."""
|
|
577
579
|
|
|
578
|
-
def actual_proxy(
|
|
579
|
-
path = self._formatted_path(
|
|
580
|
+
def actual_proxy(subpath, *kargs, **kwargs):
|
|
581
|
+
path = self._formatted_path(subpath, **kwargs)
|
|
580
582
|
if path is None:
|
|
581
583
|
raise ValueError("The archive's path is void.")
|
|
582
584
|
return pmethod(path, *kargs, **kwargs)
|
|
@@ -159,6 +159,7 @@ tests/test_ecmwf_interface.py
|
|
|
159
159
|
tests/test_env.py
|
|
160
160
|
tests/test_epygram.py
|
|
161
161
|
tests/test_gco.py
|
|
162
|
+
tests/test_geometries.py
|
|
162
163
|
tests/test_ifstools.py
|
|
163
164
|
tests/test_import.py
|
|
164
165
|
tests/test_iosponge.py
|
|
@@ -182,4 +183,5 @@ tests/test_targets.py
|
|
|
182
183
|
tests/test_templates.py
|
|
183
184
|
tests/test_toolsodb.py
|
|
184
185
|
tests/test_uget.py
|
|
186
|
+
tests/test_user_remote_dtree.py
|
|
185
187
|
tests/test_vortexnames.py
|