Fix UI/UX issues: lifecycle warnings, CORS tooltip, IAM overflow, config validation, JS maintenance

This commit is contained in:
2026-01-09 12:47:37 +08:00
parent a5d19e2982
commit c5d4b2f1cd
9 changed files with 3589 additions and 3508 deletions

View File

@@ -374,6 +374,7 @@ def bucket_detail(bucket_name: str):
kms_keys = kms_manager.list_keys() if kms_manager else [] kms_keys = kms_manager.list_keys() if kms_manager else []
kms_enabled = current_app.config.get("KMS_ENABLED", False) kms_enabled = current_app.config.get("KMS_ENABLED", False)
encryption_enabled = current_app.config.get("ENCRYPTION_ENABLED", False) encryption_enabled = current_app.config.get("ENCRYPTION_ENABLED", False)
lifecycle_enabled = current_app.config.get("LIFECYCLE_ENABLED", False)
can_manage_encryption = can_manage_versioning can_manage_encryption = can_manage_versioning
bucket_quota = storage.get_bucket_quota(bucket_name) bucket_quota = storage.get_bucket_quota(bucket_name)
@@ -418,6 +419,7 @@ def bucket_detail(bucket_name: str):
kms_keys=kms_keys, kms_keys=kms_keys,
kms_enabled=kms_enabled, kms_enabled=kms_enabled,
encryption_enabled=encryption_enabled, encryption_enabled=encryption_enabled,
lifecycle_enabled=lifecycle_enabled,
bucket_quota=bucket_quota, bucket_quota=bucket_quota,
bucket_stats=bucket_stats, bucket_stats=bucket_stats,
can_manage_quota=can_manage_quota, can_manage_quota=can_manage_quota,

View File

@@ -1,6 +1,6 @@
from __future__ import annotations from __future__ import annotations
APP_VERSION = "0.2.0" APP_VERSION = "0.2.1"
def get_version() -> str: def get_version() -> str:

46
docs.md
View File

@@ -189,6 +189,52 @@ All configuration is done via environment variables. The table below lists every
| `KMS_ENABLED` | `false` | Enable KMS key management for encryption. | | `KMS_ENABLED` | `false` | Enable KMS key management for encryption. |
| `KMS_KEYS_PATH` | `data/.myfsio.sys/keys/kms_keys.json` | Path to store KMS key metadata. | | `KMS_KEYS_PATH` | `data/.myfsio.sys/keys/kms_keys.json` | Path to store KMS key metadata. |
## Lifecycle Rules
Lifecycle rules automate object management by scheduling deletions based on object age.
### Enabling Lifecycle Enforcement
By default, lifecycle enforcement is disabled. Enable it by setting the environment variable:
```bash
LIFECYCLE_ENABLED=true python run.py
```
Or in your `myfsio.env` file:
```
LIFECYCLE_ENABLED=true
LIFECYCLE_INTERVAL_SECONDS=3600 # Check interval (default: 1 hour)
```
### Configuring Rules
Once enabled, configure lifecycle rules via:
- **Web UI:** Bucket Details → Lifecycle tab → Add Rule
- **S3 API:** `PUT /<bucket>?lifecycle` with XML configuration
### Available Actions
| Action | Description |
|--------|-------------|
| **Expiration** | Delete current version objects after N days |
| **NoncurrentVersionExpiration** | Delete old versions N days after becoming noncurrent (requires versioning) |
| **AbortIncompleteMultipartUpload** | Clean up incomplete multipart uploads after N days |
### Example Configuration (XML)
```xml
<LifecycleConfiguration>
<Rule>
<ID>DeleteOldLogs</ID>
<Status>Enabled</Status>
<Filter><Prefix>logs/</Prefix></Filter>
<Expiration><Days>30</Days></Expiration>
</Rule>
</LifecycleConfiguration>
```
### Performance Tuning ### Performance Tuning
| Variable | Default | Notes | | Variable | Default | Notes |

View File

@@ -2,6 +2,7 @@ Flask>=3.1.2
Flask-Limiter>=4.1.1 Flask-Limiter>=4.1.1
Flask-Cors>=6.0.2 Flask-Cors>=6.0.2
Flask-WTF>=1.2.2 Flask-WTF>=1.2.2
python-dotenv>=1.2.1
pytest>=9.0.2 pytest>=9.0.2
requests>=2.32.5 requests>=2.32.5
boto3>=1.42.14 boto3>=1.42.14

11
run.py
View File

@@ -6,6 +6,17 @@ import os
import sys import sys
import warnings import warnings
from multiprocessing import Process from multiprocessing import Process
from pathlib import Path
from dotenv import load_dotenv
for _env_file in [
Path("/opt/myfsio/myfsio.env"),
Path.cwd() / ".env",
Path.cwd() / "myfsio.env",
]:
if _env_file.exists():
load_dotenv(_env_file, override=True)
from app import create_api_app, create_ui_app from app import create_api_app, create_ui_app
from app.config import AppConfig from app.config import AppConfig

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -116,8 +116,8 @@
<div class="card h-100 iam-user-card"> <div class="card h-100 iam-user-card">
<div class="card-body"> <div class="card-body">
<div class="d-flex align-items-start justify-content-between mb-3"> <div class="d-flex align-items-start justify-content-between mb-3">
<div class="d-flex align-items-center gap-3"> <div class="d-flex align-items-center gap-3 min-width-0 overflow-hidden">
<div class="user-avatar user-avatar-lg"> <div class="user-avatar user-avatar-lg flex-shrink-0">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0zm4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4zm-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10z"/> <path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0zm4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4zm-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10z"/>
</svg> </svg>
@@ -127,7 +127,7 @@
<code class="small text-muted d-block text-truncate" title="{{ user.access_key }}">{{ user.access_key }}</code> <code class="small text-muted d-block text-truncate" title="{{ user.access_key }}">{{ user.access_key }}</code>
</div> </div>
</div> </div>
<div class="dropdown"> <div class="dropdown flex-shrink-0">
<button class="btn btn-sm btn-icon" type="button" data-bs-toggle="dropdown" aria-expanded="false"> <button class="btn btn-sm btn-icon" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/> <path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/>

View File

@@ -184,5 +184,5 @@ class TestPaginatedObjectListing:
assert resp.status_code == 200 assert resp.status_code == 200
html = resp.data.decode("utf-8") html = resp.data.decode("utf-8")
# Should have the JavaScript loading infrastructure # Should have the JavaScript loading infrastructure (external JS file)
assert "loadObjects" in html or "objectsApiUrl" in html assert "bucket-detail-main.js" in html