Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
53c8e47
[refactor](fe) Phase 0: Prerequisite decoupling for filesystem SPI
morningman Mar 30, 2026
a7e3a1b
[build](fe) Fix Maven build cache incorrectly skipping checkstyle
morningman Mar 30, 2026
48769c8
[fix](fe) Fix checkstyle violations introduced by Phase 0 refactoring
morningman Mar 30, 2026
913ee44
[refactor](fe) Phase 0: Prerequisite decoupling for filesystem SPI (#…
morningman Mar 30, 2026
0546905
[refactor](fe) Implement Phase 1 FS interface refactoring: new FileSy…
morningman Mar 30, 2026
c83cf7c
[refactor](fs-spi) phase1 Add unit tests for MemoryFileSystem (#61909)
morningman Mar 30, 2026
2cd3e9c
[refactor](fs-spi) Migrate cloud.storage Remote* hierarchy to fs.obj …
morningman Mar 31, 2026
23ed5e3
[refactor](fe) Phase3: split filesystem implementations into independ…
morningman Mar 31, 2026
af439c3
[refactor](fe) Phase4 P4.0: add FileSystemTransferUtil and unit tests
morningman Mar 31, 2026
a7eef55
[refactor](fe) Phase4 P4.1: add FileSystemPluginManager and plugin lo…
morningman Mar 31, 2026
52ad560
[refactor](fe) Phase4 P4.2: migrate FileSystemCache and callers to sp…
morningman Mar 31, 2026
2f4ab91
[refactor](fe) Phase4 P4.5b: migrate InsertIntoTVFCommand to spi.File…
morningman Mar 31, 2026
c47dbae
[refactor](fe) Phase4 P4.6e: replace instanceof checks with FsStorage…
morningman Mar 31, 2026
2be1cff
[feature](cloud) Migrate cloud ObjFS callers to new filesystem SPI (P…
morningman Mar 31, 2026
102fd86
[feature](fe) Migrate Iceberg DelegateFileIO to filesystem SPI (P4.4)
morningman Mar 31, 2026
3d715e2
[refactor](fe) Phase4 P4.6a-d: migrate backup domain to FileSystemDes…
morningman Mar 31, 2026
cab565c
[refactor](fe) P4.5c: S3SourceOffsetProvider SPI migration (globListW…
morningman Mar 31, 2026
8b376a6
[refactor](fe) Migrate HMSTransaction from LegacyFileSystemApi to spi…
morningman Mar 31, 2026
f084d66
[feature](fe) Implement fe-filesystem-broker SPI module and migrate B…
morningman Apr 1, 2026
af258fe
[feature](fe) Migrate Repository.java I/O path to SPI FileSystem
morningman Apr 1, 2026
6b56f77
[refactor](fe) Remove PersistentFileSystem from Repository metadata p…
morningman Apr 1, 2026
7d0cae7
[fix](fe) Fix FE build: update tests to use new StorageProperties/SPI…
morningman Apr 1, 2026
09a18f9
[fix](fe) Add missing ASF license headers to SPI service provider files
morningman Apr 1, 2026
0ed619c
[fix](fe) Fix fe-filesystem plugin module build errors and wire into …
morningman Apr 1, 2026
a4bdd5f
[fix](build) Fix dependency:copy-dependencies path for fe-filesystem …
morningman Apr 1, 2026
9eb581f
[fix](build) Handle Maven Build Cache hit missing target/lib in FE ou…
morningman Apr 1, 2026
13dc273
[refactor](fs-spi) P4.8-A: delete LegacyToNewFsAdapter and LegacyFile…
morningman Apr 1, 2026
86486c8
[refactor](fs-spi) P4.8-B: migrate DirectoryLister from RemoteFile to…
morningman Apr 1, 2026
216454f
[refactor](fs-spi) P4.8-C: delete MultipartUploadCapable interface
morningman Apr 1, 2026
3e90dc9
[refactor](fs-spi) P4.8-D: migrate HdfsStorageVault to SPI, delete le…
morningman Apr 1, 2026
9d53977
[refactor](fs-spi) P4.8-E: delete SwitchingFileSystem and dead legacy…
morningman Apr 1, 2026
59884ca
[refactor](fs-spi) P4.8-F: delete legacy BrokerFileSystem, S3FileSyst…
morningman Apr 1, 2026
a844c73
[refactor](fs-spi) P4.8-G1G2: delete dead DFSFileSystem subclasses an…
morningman Apr 1, 2026
8733d0e
[refactor](fs-spi) P4.8-G3: delete DFSFileSystem and its phantom refe…
morningman Apr 1, 2026
c6eae8d
[refactor](fs-spi) P4.8-G4G5G6H1H2: delete legacy filesystem hierarchy
morningman Apr 1, 2026
29a2c3d
[doc](fs-spi) P4.8: update progress doc to reflect all phases complete
morningman Apr 1, 2026
53e2c97
[fix](build) Fix fe-filesystem plugin build and deployment
morningman Apr 1, 2026
9d1c831
[improvement](build) Flatten filesystem plugin output layout
morningman Apr 1, 2026
7496f55
[chore](fe) Delete dead fs code: operations/, FileSystemSpiProvider, …
morningman Apr 1, 2026
61063ef
[chore](fe) Rewrite MemoryFileSystem for spi.FileSystem; delete old f…
morningman Apr 1, 2026
a46e1fa
[chore](fe) Delete fs/obj/ and migrate callers to spi.ObjStorage
morningman Apr 1, 2026
c60d5de
[refactor](fe) Migrate FileSystemTransferUtil to fe-filesystem-spi mo…
morningman Apr 1, 2026
99ff71c
[refactor](fe) Migrate pure-SPI classes from org.apache.doris.fs to f…
morningman Apr 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,14 @@ if [[ "${BUILD_FE}" -eq 1 ]]; then
modules+=("fe-extension-spi")
modules+=("fe-extension-loader")
modules+=("fe-core")
# Filesystem SPI plugin modules (loaded at runtime as plugins)
modules+=("fe-filesystem/fe-filesystem-spi")
for _fs_mod in s3 oss cos obs azure hdfs local broker; do
if [[ -d "${DORIS_HOME}/fe/fe-filesystem/fe-filesystem-${_fs_mod}" ]]; then
modules+=("fe-filesystem/fe-filesystem-${_fs_mod}")
fi
done
unset _fs_mod
if [[ "${WITH_TDE_DIR}" != "" ]]; then
modules+=("fe-${WITH_TDE_DIR}")
fi
Expand Down Expand Up @@ -913,6 +921,17 @@ if [[ "${BUILD_FE}" -eq 1 ]]; then
if [[ "${BUILD_JUICEFS}" == "ON" ]]; then
install -d "${DORIS_OUTPUT}/fe/lib/juicefs"
fi
# Maven Build Cache may restore only the JAR on a cache hit, skipping the
# dependency:copy-dependencies execution that populates target/lib/. Run it
# explicitly when needed so the output lib directory is always complete.
if [[ ! -d "${DORIS_HOME}/fe/fe-core/target/lib" ]]; then
echo "target/lib not found (build cache hit), running dependency:copy-dependencies..."
(cd "${DORIS_HOME}/fe" && "${MVN_CMD}" dependency:copy-dependencies \
-pl fe-core \
-DoutputDirectory="${DORIS_HOME}/fe/fe-core/target/lib" \
-DincludeScope=runtime \
--no-transfer-progress -q)
fi
cp -r -p "${DORIS_HOME}/fe/fe-core/target/lib"/* "${DORIS_OUTPUT}/fe/lib"/
cp -r -p "${DORIS_HOME}/fe/fe-core/target/doris-fe.jar" "${DORIS_OUTPUT}/fe/lib"/
if [[ "${WITH_TDE_DIR}" != "" ]]; then
Expand Down Expand Up @@ -952,6 +971,27 @@ if [[ "${BUILD_FE}" -eq 1 ]]; then
mkdir -p "${DORIS_OUTPUT}/fe/plugins/hadoop_conf/"
mkdir -p "${DORIS_OUTPUT}/fe/plugins/java_extensions/"

# Deploy filesystem provider plugins as independent plugin directories
# Each sub-directory is one storage backend loaded at runtime by FileSystemPluginManager.
FS_PLUGIN_DIR="${DORIS_OUTPUT}/fe/plugins/filesystem"
for fs_module in s3 azure oss cos obs hdfs local broker; do
fs_plugin_target="${FS_PLUGIN_DIR}/${fs_module}"
fs_module_dir="${DORIS_HOME}/fe/fe-filesystem/fe-filesystem-${fs_module}"
if [ ! -d "${fs_module_dir}" ]; then
continue
fi
mkdir -p "${fs_plugin_target}"
# Copy main JAR
cp -f "${fs_module_dir}/target/doris-fe-filesystem-${fs_module}"*.jar "${fs_plugin_target}/" 2>/dev/null || true
# Copy transitive dependencies flat into the same directory, excluding spi JARs already on FE classpath
(cd "${DORIS_HOME}/fe" && "${MVN_CMD}" dependency:copy-dependencies \
-pl "fe-filesystem/fe-filesystem-${fs_module}" \
-DoutputDirectory="${fs_plugin_target}" \
-DexcludeArtifactIds="fe-filesystem-spi,fe-extension-spi" \
--no-transfer-progress -q 2>/dev/null) || true
done
unset FS_PLUGIN_DIR fs_module fs_plugin_target fs_module_dir

if [ "${TARGET_SYSTEM}" = "Darwin" ] || [ "${TARGET_SYSTEM}" = "Linux" ]; then
mkdir -p "${DORIS_OUTPUT}/fe/arthas"
rm -rf "${DORIS_OUTPUT}/fe/arthas/*"
Expand Down
5 changes: 5 additions & 0 deletions conf/fe.conf
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,8 @@ sys_log_mode = ASYNC
# qe_max_connection = 1024
# qe_query_timeout_second = 300
# qe_slow_log_ms = 5000

# Directory containing filesystem provider plugin subdirectories.
# Each subdirectory is one storage backend (e.g., s3/, hdfs/, azure/).
# If empty, only classpath-based built-in providers are used.
# filesystem_plugin_root = ${DORIS_HOME}/plugins/filesystem
16 changes: 16 additions & 0 deletions fe/.mvn/maven-build-cache-config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ under the License.
<glob>{*.java,*.g4,*.xml,*.properties}</glob>
<includes>
<include>src/</include>
<!-- Checkstyle configuration files affect all modules' style checks.
Include them globally so any change to checkstyle rules invalidates
all cached checkstyle results. -->
<include glob="{*.xml,*.txt}" recursive="true">check/checkstyle</include>
<!-- External source directories under gensrc/ are referenced by plugins via
Maven properties (e.g. ${project.parent.basedir}/../gensrc/thrift).
The cache extension's tagScanConfig cannot resolve these Maven properties,
Expand All @@ -44,4 +48,16 @@ under the License.
</includes>
</global>
</input>
<executionControl>
<runAlways>
<!-- Checkstyle is a quality gate that must always execute; never use a cached result. -->
<executions>
<execution artifactId="maven-checkstyle-plugin">
<execIds>
<execId>validate</execId>
</execIds>
</execution>
</executions>
</runAlways>
</executionControl>
</cache>
Original file line number Diff line number Diff line change
Expand Up @@ -3424,6 +3424,11 @@ public static int metaServiceRpcRetryTimes() {
@ConfField(description = {"Security plugin directory."})
public static String security_plugins_dir = EnvUtils.getDorisHome() + "/plugins/security";

@ConfField(description = {"Directory containing filesystem provider plugin subdirectories. "
+ "Each subdirectory is one storage backend (e.g., s3/, hdfs/, azure/). "
+ "If empty, only classpath-based built-in providers are used (test/dev mode)."})
public static String filesystem_plugin_root = EnvUtils.getDorisHome() + "/plugins/filesystem";

@ConfField(description = {"Authorization plugin configuration file path. Must be under DORIS_HOME. "
+ "Default is conf/authorization.conf."})
public static String authorization_config_file_path = "/conf/authorization.conf";
Expand Down
16 changes: 16 additions & 0 deletions fe/fe-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,22 @@ under the License.
<artifactId>fe-common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- fe-filesystem-spi: compile-time SPI interfaces for FileSystemFactory -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>fe-filesystem-spi</artifactId>
<version>${project.version}</version>
</dependency>
<!-- fe-filesystem impl modules: runtime dependencies removed in Phase 4 P4.1.
Providers are now loaded from plugins/filesystem/ directory at startup
via FileSystemPluginManager + DirectoryPluginRuntimeManager. -->
<!-- fe-filesystem-local: test-scope only, used for unit testing FileSystemTransferUtil etc. -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>fe-filesystem-local</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>fe-thrift</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@
import org.apache.doris.common.util.TimeUtils;
import org.apache.doris.common.util.Util;
import org.apache.doris.datasource.property.storage.StorageProperties;
import org.apache.doris.fs.FileSystemFactory;
import org.apache.doris.fs.remote.RemoteFileSystem;
import org.apache.doris.info.TableNameInfo;
import org.apache.doris.info.TableRefInfo;
import org.apache.doris.nereids.trees.plans.commands.BackupCommand;
Expand Down Expand Up @@ -208,11 +206,9 @@ public void createRepository(CreateRepositoryCommand command) throws DdlExceptio
"broker does not exist: " + command.getBrokerName());
}

RemoteFileSystem fileSystem;
fileSystem = FileSystemFactory.get(command.getStorageProperties());
long repoId = env.getNextId();
Repository repo = new Repository(repoId, command.getName(), command.isReadOnly(), command.getLocation(),
fileSystem);
command.getStorageProperties());

Status st = repoMgr.addAndInitRepoIfNotExist(repo, false);
if (!st.ok()) {
Expand Down Expand Up @@ -244,12 +240,10 @@ public void alterRepository(String repoName, Map<String, String> newProps)
}
// Merge new properties with the existing repository's properties
Map<String, String> mergedProps = mergeProperties(oldRepo, newProps);
// Create new remote file system with merged properties
RemoteFileSystem fileSystem = FileSystemFactory.get(StorageProperties.createPrimary(mergedProps));
// Create new Repository instance with updated file system
// Create new Repository instance with merged properties
Repository newRepo = new Repository(
oldRepo.getId(), oldRepo.getName(), oldRepo.isReadOnly(),
oldRepo.getLocation(), fileSystem
oldRepo.getLocation(), StorageProperties.createPrimary(mergedProps)
);
// Verify the repository can be connected with new settings
if (!newRepo.ping()) {
Expand Down Expand Up @@ -277,7 +271,7 @@ public void alterRepository(String repoName, Map<String, String> newProps)
*/
private Map<String, String> mergeProperties(Repository repo, Map<String, String> newProps) {
// General case: just override old props with new ones
Map<String, String> combined = new HashMap<>(repo.getRemoteFileSystem().getProperties());
Map<String, String> combined = new HashMap<>(repo.getFileSystemDescriptor().getProperties());
combined.putAll(newProps);
return combined;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ public synchronized Status updateRepo(Repository repo) {
continue;
}
((UploadTask) task).updateBrokerProperties(
repo.getRemoteFileSystem().getStorageProperties().getBackendConfigProperties());
repo.getFileSystemDescriptor().getBackendConfigProperties());
AgentTaskQueue.updateTask(beId, TTaskType.UPLOAD, signature, task);
}
LOG.info("finished to update upload job properties. {}", this);
Expand Down Expand Up @@ -821,8 +821,8 @@ private void uploadSnapshot() {
long signature = env.getNextId();
UploadTask task = new UploadTask(null, beId, signature, jobId, dbId, srcToDest,
brokers.get(0),
repo.getRemoteFileSystem().getStorageProperties().getBackendConfigProperties(),
repo.getRemoteFileSystem().getStorageType(), repo.getLocation());
repo.getFileSystemDescriptor().getBackendConfigProperties(),
repo.getFileSystemDescriptor().getThriftStorageType(), repo.getLocation());
batchTask.addTask(task);
unfinishedTaskIds.put(signature, beId);
}
Expand Down
Loading
Loading