Skip to content

Commit 647ffc5

Browse files
authored
Merge branch 'master' into cmdguard2
2 parents ac47430 + f966f0f commit 647ffc5

180 files changed

Lines changed: 24958 additions & 19265 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/codeql-analysis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646

4747
# Initializes the CodeQL tools for scanning.
4848
- name: Initialize CodeQL
49-
uses: github/codeql-action/init@19b2f06db2b6f5108140aeb04014ef02b648f789 # v3.29.5
49+
uses: github/codeql-action/init@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v3.29.5
5050
with:
5151
languages: ${{ matrix.language }}
5252
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -66,4 +66,4 @@ jobs:
6666
# make release
6767

6868
- name: Perform CodeQL Analysis
69-
uses: github/codeql-action/analyze@19b2f06db2b6f5108140aeb04014ef02b648f789 # v3.29.5
69+
uses: github/codeql-action/analyze@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v3.29.5
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
name: PR Quota Limit
2+
3+
on:
4+
pull_request:
5+
types: [opened, reopened]
6+
7+
permissions:
8+
contents: read
9+
pull-requests: read
10+
11+
jobs:
12+
check-pr-quota:
13+
runs-on: ubuntu-latest
14+
permissions:
15+
pull-requests: write
16+
issues: write
17+
steps:
18+
- name: Check PR quota
19+
// Use action version v7.0.1
20+
uses: actions/github-script@60a0d8304218317a38b4124020f343a0d555a1eb
21+
with:
22+
script: |
23+
try {
24+
const prAuthor = context.payload.pull_request.user.login;
25+
const currentPRNumber = context.payload.pull_request.number;
26+
27+
console.log(`Checking PR quota for user: ${prAuthor}`);
28+
console.log(`Current PR number: ${currentPRNumber}`);
29+
30+
// Get all open PRs with pagination support
31+
let allPRs = [];
32+
let page = 1;
33+
let hasMorePages = true;
34+
35+
while (hasMorePages) {
36+
const { data: prs } = await github.rest.pulls.list({
37+
owner: context.repo.owner,
38+
repo: context.repo.repo,
39+
state: 'open',
40+
per_page: 100,
41+
page: page
42+
});
43+
44+
allPRs = allPRs.concat(prs);
45+
46+
// If we got less than 100 PRs, we've reached the last page
47+
if (prs.length < 100) {
48+
hasMorePages = false;
49+
} else {
50+
page++;
51+
}
52+
}
53+
54+
console.log(`Total open PRs in repository: ${allPRs.length}`);
55+
56+
// Filter PRs by the same author
57+
const userPRs = allPRs.filter(pr => pr.user.login === prAuthor);
58+
const openCount = userPRs.length;
59+
60+
console.log(`User ${prAuthor} has ${openCount} open PR(s)`);
61+
62+
// Check if exceeds quota (15 PRs max)
63+
const maxPRs = 15;
64+
if (openCount > maxPRs) {
65+
const currentStatus = `${openCount}/${maxPRs}`;
66+
67+
const message = `Hi, @${prAuthor}, Thanks for your contribution! To ensure quality reviews, we limit how many concurrent open PRs contributors can open. This pull request will be temporarily closed (Current status: ${currentStatus} open). We encourage you to submit a new PR once the quota policy permits future contributions.`;
68+
69+
console.log(`Quota exceeded! Closing PR #${currentPRNumber}`);
70+
console.log(`User has ${openCount} open PRs, which exceeds the limit of ${maxPRs}`);
71+
console.log(`Message: ${message}`);
72+
73+
// Add comment to the PR
74+
try {
75+
await github.rest.issues.createComment({
76+
owner: context.repo.owner,
77+
repo: context.repo.repo,
78+
issue_number: currentPRNumber,
79+
body: message
80+
});
81+
console.log('Comment added successfully');
82+
} catch (commentError) {
83+
console.error('Failed to add comment:', commentError.message);
84+
}
85+
86+
// Close the PR
87+
try {
88+
await github.rest.pulls.update({
89+
owner: context.repo.owner,
90+
repo: context.repo.repo,
91+
pull_number: currentPRNumber,
92+
state: 'closed'
93+
});
94+
console.log(`PR #${currentPRNumber} has been closed due to quota limit.`);
95+
} catch (closeError) {
96+
console.error('Failed to close PR:', closeError.message);
97+
throw closeError; // Re-throw to fail the workflow
98+
}
99+
} else {
100+
const availableSlots = maxPRs - openCount;
101+
console.log(`Quota check passed. User has ${availableSlots} slot(s) available.`);
102+
}
103+
} catch (error) {
104+
console.error('Error in PR quota check:', error.message);
105+
throw error; // Re-throw to fail the workflow
106+
}

.github/workflows/sonarcloud.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,6 @@ jobs:
5151
retention-days: 5
5252

5353
- name: "Upload to code-scanning"
54-
uses: github/codeql-action/upload-sarif@19b2f06db2b6f5108140aeb04014ef02b648f789 # v2.22.11
54+
uses: github/codeql-action/upload-sarif@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v2.22.11
5555
with:
5656
sarif_file: results.sarif

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ bin
2424
*.swo
2525
*~
2626
.vscode
27+
.qoder
2728

2829
**/*.tgz
2930
**/.DS_Store

CONTRIBUTING.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ Go to the "Pull requests" tab page under your repository and Click the "New Pull
104104
105105
To help reviewers better get your purpose, PR title should be descriptive enough but not too long. It's also recommended that you follow the [PR template](.github/PULL_REQUEST_TEMPLATE.md) as your PR description.
106106

107+
#### PR Quota Policy
108+
To maintain code quality and avoid conflicts, we enforce a limit on the number of open pull requests per contributor. Each contributor can have a **maximum of 15 open pull requests** at any given time. If you attempt to open or reopen a pull request when you already have 15 open PRs, the pull request will be automatically closed with a notification message. Please wait for some of your existing PRs to be merged or closed before submitting or reopening additional ones.
109+
107110
### Tracking Your PR
108111
Once you've submitted the PR to the Fluid project, your PR will be reviewed. Please keep tracking the status of your PR, make responses to the reviewers' comments and update your changes if needed to make your PR get accepted.
109112

ROADMAP.md

Lines changed: 75 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,78 @@
11
# Fluid Roadmap
22

3-
## Fluid 2025 Roadmap
4-
5-
### **1. Data Anyway**
6-
**Objective**: Enable fluid data access **regardless of infrastructure constraints** (e.g., storage types, runtime environments) without developing controller code.
7-
8-
- **Unified Cache Runtime Framework**
9-
- Enable integration of new cache runtimes(e.g., Cubefs, DragonFly) via a **generic Cache Runtime interface** with minimal code changes.
10-
- Standardize APIs for cache engine compatibility (e.g., Alluxio, Vineyard, JuiceFS).
11-
- **Adaptive Data Access**:
12-
- Data Access Mode based on Scheduler's Decsion:
13-
- *Shared-Kernel Nodes* → Use CSI plugins for direct mounting.
14-
- *Kata Containers* → Switch to sidecar-based container.
15-
- **ThinRuntime Productization**:
16-
- Improve stability and performance for large-scale deployments.
17-
- Minimum container permission (remove the privileged permission of FUSE Pod)
18-
19-
20-
### **2. Data Anywhere**
21-
**Objective**: Achieve **cross-region, cross-cluster, and cross-platform** data mobility and accessibility.
22-
23-
- **Multi-Cluster Dataset Unified Management**
24-
- **Global Dataset**: Create datasets pointing to the same data source across clusters.
25-
- **Queue Integration**: Orchestrate dependencies between data preparation and task scheduling.
26-
- **Persistent Data Mirroring**
27-
- **Region-Aware Replication**: Automatically mirror datasets across clouds/regions.
28-
- **Consistency Guarantees**: Support both eventual and strong consistency models.
29-
30-
- **Efficient Data Prewarming & Migration**
31-
- **Distributed Prewarming**: Maximize bandwidth utilization for fast data loading.
32-
- **Throttling Control**: Limit bandwidth usage during prewarming to avoid saturation.
33-
- **Rsync Optimization**: Improve cross-region sync efficiency.
34-
35-
- **Elastic Caching & Scheduling**:
36-
- **Disk-Aware Scheduling**: Optimize workload placement based on disk capacity, utilization, and locality.
37-
- **Intelligent Scaling**:
38-
- Recommend underutilized Pods for scaling (cost/performance-aware).
39-
- Ensure cache engines adapt to dynamic throughput post-scaling.
40-
- **Cloud-Agnostic Recovery**: Rebuild caches across regions using cloud disk snapshots.
41-
42-
- **Observability-Driven Optimization**
43-
- **Pattern Recognition**: Analyze data access patterns to auto-inject acceleration components (e.g., caching, prefetching).
44-
- **Idle Dataset Detection**: Identify unused datasets via reference counting and access history.
45-
46-
- **Application-Side Acceleration**
47-
- **Transparent Prefetching**:
48-
- Inject sidecar containers to prefetch data dynamically (e.g., Alluxio/Fluid Runtime).
49-
- Auto-adjust prefetch strategies (block size, concurrency) based on access patterns.
50-
- **Dynamic SDK Injection**: Attach acceleration SDKs to Pods via Fluid Admission Controller (no base image modification).
51-
52-
53-
### **3. Data Anytime**
54-
**Core Goal**: Ensure **real-time, adaptive, and intelligent** data availability for workloads.
55-
56-
- **Temporal Workflows with Kueue**:
57-
- Trigger ML jobs (TFJob, PyTorchJob) **after prewarming completes**.
58-
- Automate post-job cleanup (data migration/cache eviction).
59-
- **Dynamic Volume Mounting**:
60-
- Support dynamic volume mounting capabilities for multi-cloud/hybrid-cloud scenarios.
61-
- Enable dyanmic data mount operations in Python SDK.
3+
## Fluid 2026 Roadmap
624

5+
### 1. Data Anyway
6+
7+
> **Objective:** Enable fluid data access **regardless of infrastructure constraints** (e.g., storage types, runtime environments) without developing controller code.
8+
9+
#### Generic Cache Runtime
10+
11+
- **Pluggable Architecture:** Standardized Cache Runtime Interface for rapid integration of new engines (CubeFS, Dragonfly, Vineyard) with minimal boilerplate.
12+
- **Orchestration Based on AdvancedStatefulSet:** Migrate from StatefulSet to AdvancedStatefulSet for fine-grained Pod lifecycle management, ordered rollout, and enhanced failover capabilities.
13+
14+
#### Runtime Dynamic Configuration
15+
16+
- **Zero-Downtime Tuning:** Adjust cache replicas, storage media tiers (SSD/HDD/RAM), and eviction policies without Dataset reconstruction or workload restart.
17+
- **Hot Parameter Swapping:** Runtime modification of cache engine configurations (e.g., Alluxio thread pool, Jindo worker threads) for traffic spike handling.
18+
19+
#### API Upgrade to `v1alpha2`
20+
21+
- Standardized Conditions, `ObservedGeneration`, and phase transition semantics for improved GitOps and tooling compatibility.
22+
- Conversion webhook support for seamless `v1alpha1``v1alpha2` migration.
23+
24+
#### Validation Webhook
25+
26+
- Admission-time CRD validation with auto-correction suggestions to prevent misconfigurations.
27+
- Policy enforcement for resource quotas and security constraints.
28+
29+
#### ThinRuntime Productization
30+
31+
- Production-ready stability for large-scale deployments with **minimum container privileges** (eliminate privileged FUSE Pod requirements).
32+
33+
---
34+
35+
### 2. Data Anywhere
36+
37+
> **Objective:** Achieve **cross-region, cross-cluster, and cross-platform** data mobility and accessibility.
38+
39+
#### LLM KV Cache Orchestration
40+
41+
- **Disaggregated KV Cache:** Externalize vLLM/SGLang KV Cache to Fluid-managed distributed storage, enabling 10x+ throughput improvement for long-context inference.
42+
- **Cross-Pod Cache Sharing:** Live migration of KV Cache between inference instances for preemptive scheduling and spot instance tolerance.
43+
- **Mooncake Integration:** Official partnership for high-performance KV Cache backend with RDMA acceleration.
44+
45+
#### Efficient Data Prewarming & Migration
46+
47+
- **Distributed Prewarming:** Maximize bandwidth utilization for fast data loading.
48+
- **Throttling Control:** Limit bandwidth usage during prewarming to avoid saturation.
49+
- **Rsync Optimization:** Improve cross-region sync efficiency.
50+
51+
#### JindoRuntime High Availability
52+
53+
- **Master Pod Crash Recovery:** Automatic re-setup and state reconstruction after cache master failure without data loss.
54+
- **Metadata Persistence:** WAL-based metadata recovery for rapid failover.
55+
56+
#### Observability-Driven Optimization
57+
58+
- **Access Pattern Recognition:** ML-based analysis to auto-inject acceleration strategies (prefetching, block size optimization).
59+
- **Dataset Garbage Collection:** Idle dataset detection via reference counting and access history analysis.
60+
61+
---
62+
63+
### 3. Data Anytime
64+
65+
> **Objective:** Ensure **real-time, adaptive, and intelligent** data availability for workloads.
66+
67+
#### Temporal Workflow Integration
68+
69+
- **Kueue-Driven Pipelines:** Trigger training/inference jobs automatically upon DataLoad completion; automate post-job cache eviction and data migration.
70+
- **Event-Driven Policies:** Flexible metadata synchronization triggered by workload lifecycle events.
71+
72+
#### Developer Experience
73+
74+
- **Fluid kubectl Plugin:** Native CLI extension (`kubectl fluid`) for:
75+
- Dataset status inspection and health diagnostics
76+
- On-demand prewarming triggering (`kubectl fluid warmup`)
77+
- Cache performance profiling and bottleneck analysis
78+
- Runtime configuration hot-updates

addons/3fs/dev-guide/Dockerfile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ ARG FOUNDATIONDB_TAG=7.3.59
66
ARG FOUNDATIONDB_VERSION=${FOUNDATIONDB_TAG}-1
77
ARG LIBFUSE_TAG=fuse-3.16.1
88
ARG LIBFUSE_VERSION=3.16.1
9+
ARG RUSTUP_VERSION=1.27.1
10+
ARG RUSTUP_INIT_SHA256=f39939f3c83a31eda563840394548455a095842de8467556748c55a9346a4959
911

1012
# Install system dependencies and build tools
1113
RUN apt update && \
@@ -22,8 +24,8 @@ RUN apt update && \
2224
    rm -rf /var/lib/apt/lists/* apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb
2325

2426
# Install Rust
25-
RUN wget -O rustup-init "https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init" && \
26-
echo "f39939f3c83a31eda563840394548455a095842de8467556748c55a9346a4959 *rustup-init" | sha256sum -c - && \
27+
RUN wget -O rustup-init "https://static.rust-lang.org/rustup/archive/${RUSTUP_VERSION}/x86_64-unknown-linux-gnu/rustup-init" && \
28+
echo "${RUSTUP_INIT_SHA256} *rustup-init" | sha256sum -c - && \
2729
chmod +x rustup-init && \
2830
./rustup-init -y --no-modify-path --default-toolchain 1.90.0 && \
2931
rm rustup-init

addons/glusterfs/docker/entrypoint.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,36 @@
11
import json
22
import os
3+
import re
34
import subprocess
45

56
obj = json.load(open("/etc/fluid/config/config.json"))
67

78
mount_point = obj["mounts"][0]["mountPoint"]
89
target_path = obj["targetPath"]
910

11+
# Normalize first to resolve redundant separators, '.' and '..' components
12+
target_path = os.path.normpath(target_path)
13+
14+
# Validate that the normalized path is an absolute POSIX path
15+
if not os.path.isabs(target_path) or not target_path.startswith('/'):
16+
print(f"Error: target_path must be absolute: {target_path}")
17+
exit(1)
18+
19+
# Safety check: ensure no '..' components remain after normalization
20+
if '..' in target_path.split('/'):
21+
print(f"Error: Path traversal using '..' is not allowed in target_path: {target_path}")
22+
exit(1)
23+
24+
# Validate that the path contains only safe characters
25+
if not re.match(r'^[/a-zA-Z0-9._-]+$', target_path):
26+
print(f"Error: target_path contains invalid characters: {target_path}")
27+
exit(1)
28+
29+
# Prevent mounting on the root directory
30+
if target_path == '/':
31+
print("Error: target_path resolves to the root directory '/' and is not allowed.")
32+
exit(1)
33+
1034
os.makedirs(target_path, exist_ok=True)
1135

1236
if len(mount_point.split(":")) != 2:

0 commit comments

Comments
 (0)