Overview
Fluxon FS lets you mount a remote export into the current Python process and keep using open() / read() / write() semantics.
The core objects are:
- KV service-plane objects:
etcd,greptime,master,owner - FS role objects:
fs_master,fs_agent - In-process mount objects:
FluxonKvClientConfig,new_store(...),FluxonFsPatcher,mount_remote_dir(...)
etcd + greptime + fluxonkv master + owner
|
v
fluxon_fs master
|
v
fluxon_fs agent
|
v
FluxonKvClientConfig -> new_store(...) -> KvClient(store)
|
v
FluxonFsPatcher(store)
|
+-- set_master_config_yaml(...)
+-- set_cache_config_yaml(...)
+-- set_request_identity(...)
+-- install()
+-- mount_remote_dir(...)
|
v
open() / read() / write() / close()See Architecture and Concepts for the role model and User - 3 - KV and RPC Interface for FluxonKvClientConfig and new_store(...).
Service Plane
FS depends on the KV service plane and then adds two more roles on top:
greptimeetcdfluxonkv masterownerfs masterfs agent- your mount verification script
examples/start_kv_and_fs_svc.py only starts Fluxon-native roles. etcd and greptime still follow User - 2 - Service Plane. If you need /ui/transfers/ and pre-scan, start the TiKV PD / TiKV pair for transfer_state_store first.
fs_master and fs_agent
After the KV service plane is ready, FS adds two roles:
fs_master: attaches to the KV plane as an external client and owns panel / export snapshot distributionfs_agent: registers exports tofs_masterand exposes remote directory access
The reference script is examples/start_kv_and_fs_svc.py.
Start it with:
python3 examples/start_kv_and_fs_svc.py
python3 examples/start_kv_and_fs_svc.py --without-masterDefault mode starts kv master + owner + fs master + fs agent. --without-master only starts owner + fs_agent and expects the cluster’s kv master and fs master to already exist elsewhere.
Most important remote-agent constraints:
ETCD_ENDPOINTmust point at the real cluster etcd endpointFS_MASTER_INSTANCE_KEYmust match the existingfs masterOWNER_INSTANCE_KEY,FS_AGENT_INSTANCE_KEY,EXPORT_NAME, andREMOTE_ROOT_DIRmust be unique per agent machineFS_PANEL_PUBLIC_BASE_URLcontrols external links shown by the UI, whileFS_PANEL_LISTEN_ADDRonly controls the bind address
Default mode collects subprocess stdout/stderr into WORKDIR/log and keeps only summary output in the terminal.
Remote Mount Read / Write Verification
The public FS verification flow under examples/ is:
examples/start_kv_and_fs_svc.pyexamples/start_fluxon_fs_writer.pyexamples/start_fluxon_fs_reader.py
Minimum success path:
- run
python3 examples/start_kv_and_fs_svc.py - keep it running
- prepare writer config and run
python3 examples/start_fluxon_fs_writer.py -c <writer-config.yaml> -w <writer-workdir> - prepare reader config and run
python3 examples/start_fluxon_fs_reader.py -c <reader-config.yaml> -w <reader-workdir>
The reader side always does three things:
- attach to the local owner through one external client
- install the patcher through
install_patcher_from_master(...) - mount the selected export and alternate between remote and local reads
Once the reader keeps printing op=read_remote / op=read_local, the remote mount chain and local cache rules are both working.
Directory Transfer and Pre-Scan
Directory transfer and pre-scan are designed for long-running large-folder jobs such as cross-cluster migration or migration across shared-storage domains.
The main user-facing UI is /ui/transfers/, which exposes:
Pre-ScansFluxonFS Transfer Jobs
Typical direct-transfer flow from the UI:
- open two panes
- locate the source folder on the left
- locate the target export and target directory on the right
- drag the folder across panes
- fill
desired_worker_countandbatch_ready_bytes - submit and inspect the job in
/ui/transfers/
Typical pre-scan import flow:
- open
/ui/transfers/ - find the record in
Pre-Scans - click
Import - choose
source export - choose
target export - fill
target prefix - fill
desired_worker_count - submit
TiKV Config for Transfer State
Directory transfer and pre-scan both depend on transfer_state_store. The fs master panel and any standalone pre-scan process must share the same TiKV namespace.
The most important fields are:
pd_endpointskey_prefix
The start_kv_and_fs_svc.py example uses:
TRANSFER_STATE_STORE_PD_ENDPOINTS = ["127.0.0.1:12379"]TRANSFER_STATE_STORE_KEY_PREFIX = "/fluxon_fs_transfer/demo-fs-cluster/"
fs master needs:
transfer_state_store:
kind: tikv
tikv:
pd_endpoints:
- "127.0.0.1:12379"
key_prefix: "/fluxon_fs_transfer/demo-fs-cluster/"Standalone pre-scan code must use the same values.
Standalone Pre-Scan Example
#!/usr/bin/env python3
from fluxon_py.fluxon_fs import (
FluxonFsTransferSkipEntry,
FluxonFsTransferSkipEntryKind,
FluxonFsTransferStateStoreConfig,
FluxonFsTransferStateStoreKind,
FluxonFsTransferStateStoreTiKvConfig,
transfer_check_local_blocking,
)
STORE = FluxonFsTransferStateStoreConfig(
kind=FluxonFsTransferStateStoreKind.TIKV,
tikv=FluxonFsTransferStateStoreTiKvConfig(
pd_endpoints=["127.0.0.1:12379"],
key_prefix="/fluxon_fs_transfer/demo_prescan/",
),
)
summary = transfer_check_local_blocking(
src_root_dir="/data/demo_src",
transfer_state_store=STORE,
batch_ready_bytes=8 * 1024 * 1024 * 1024,
skip_entries=[
FluxonFsTransferSkipEntry(
kind=FluxonFsTransferSkipEntryKind.DIR,
relpath="tmp",
),
FluxonFsTransferSkipEntry(
kind=FluxonFsTransferSkipEntryKind.FILE,
relpath="logs/debug.txt",
),
],
checker_concurrency_limit=4,
enable_cli_progress=True,
)
print(summary)summary is most useful for job_id, scan_epoch, and batch_count.
FluxonFsPatcher
FluxonFsPatcher is not a standalone public entrypoint. It must sit on top of the store returned by new_store(...).
Required order:
store = new_store(cfg)...patcher = FluxonFsPatcher(store)patcher.set_master_config_yaml(...)patcher.set_cache_config_yaml(...)patcher.set_request_identity(...)patcher.install()patcher.mount_remote_dir(...)open()/read()/write()patcher.uninstall()store.close()
Do not close store before patcher.uninstall().
Config Injection
set_master_config_yaml(...): injectsfluxon_fs.master.instance_keyset_cache_config_yaml(...): injects the current export snapshotset_request_identity(username, password): binds later FS requests to one identity
User-facing examples should set identity explicitly instead of depending on an implicit unauthenticated path.
bootstrap_access_model
bootstrap_access_model is a required startup-time seed for an empty access_db.
fluxon_fs:
master_panel:
access_db_path: /path/to/access.db
bootstrap_access_model:
users:
- username: admin
password: admin
can_manage_users: true
scope_access: []Rules:
access_db_pathis the long-lived authoritybootstrap_access_modelmust be provided explicitly in startup config- it only writes when
access_dbhas no users yet - once users already exist, restarts follow the database state
can_manage_users: truegrants runtime access to all current exports without writing synthetic root scopes
Mount Directory Rules
mount_remote_dir(local_mount_dir_abs=..., export_name=...) requires:
- an absolute path
- not
/ - if the directory does not exist, Fluxon creates it
- if the directory already exists, it must be empty
- it must not overlap with another mount path in the same process
Logging
For more Python-side logs:
FLUXON_LOG=DEBUG python3 examples/start_fluxon_fs_reader.py -c <reader-config.yaml> -w <reader-workdir>Common levels:
DEBUGINFOWARNINGERRORCRITICAL
Common Errors
new_store failed
Usually means the external client did not attach to the local owner. Check:
- whether
start_kv_and_fs_svc.pyis still running CLUSTER_NAMESHARED_MEMORY_PATHSHARED_FILE_PATH
fluxon_fs cache config is not loaded yet
Usually means set_cache_config_yaml(...) did not complete successfully, or the client-side cache config does not match the current server export config. Check:
FS_MASTER_INSTANCE_KEYEXPORT_NAMEREMOTE_ROOT_DIR
unknown export_name
The client is trying to mount an EXPORT_NAME that does not exist in the current fs master export snapshot. Check:
- whether writer and reader use the same
export_name - whether
REMOTE_ROOT_DIRmatches the export definition
permission denied or PermissionError
The path exists but the current identity does not have access. Check:
ADMIN_USERNAMEADMIN_PASSWORD- whether the current
access_dbwas already overwritten by newer user data
If the admin password was changed through the UI or the database, the old bootstrap_access_model password no longer applies.