Fix UI/UX issues: lifecycle warnings, CORS tooltip, IAM overflow, config validation, JS maintenance
This commit is contained in:
@@ -374,6 +374,7 @@ def bucket_detail(bucket_name: str):
|
||||
kms_keys = kms_manager.list_keys() if kms_manager else []
|
||||
kms_enabled = current_app.config.get("KMS_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
|
||||
|
||||
bucket_quota = storage.get_bucket_quota(bucket_name)
|
||||
@@ -418,6 +419,7 @@ def bucket_detail(bucket_name: str):
|
||||
kms_keys=kms_keys,
|
||||
kms_enabled=kms_enabled,
|
||||
encryption_enabled=encryption_enabled,
|
||||
lifecycle_enabled=lifecycle_enabled,
|
||||
bucket_quota=bucket_quota,
|
||||
bucket_stats=bucket_stats,
|
||||
can_manage_quota=can_manage_quota,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
APP_VERSION = "0.2.0"
|
||||
APP_VERSION = "0.2.1"
|
||||
|
||||
|
||||
def get_version() -> str:
|
||||
|
||||
46
docs.md
46
docs.md
@@ -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_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
|
||||
|
||||
| Variable | Default | Notes |
|
||||
|
||||
@@ -2,6 +2,7 @@ Flask>=3.1.2
|
||||
Flask-Limiter>=4.1.1
|
||||
Flask-Cors>=6.0.2
|
||||
Flask-WTF>=1.2.2
|
||||
python-dotenv>=1.2.1
|
||||
pytest>=9.0.2
|
||||
requests>=2.32.5
|
||||
boto3>=1.42.14
|
||||
|
||||
11
run.py
11
run.py
@@ -6,6 +6,17 @@ import os
|
||||
import sys
|
||||
import warnings
|
||||
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.config import AppConfig
|
||||
|
||||
3503
static/js/bucket-detail-main.js
Normal file
3503
static/js/bucket-detail-main.js
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -116,8 +116,8 @@
|
||||
<div class="card h-100 iam-user-card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-start justify-content-between mb-3">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="user-avatar user-avatar-lg">
|
||||
<div class="d-flex align-items-center gap-3 min-width-0 overflow-hidden">
|
||||
<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">
|
||||
<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>
|
||||
@@ -127,7 +127,7 @@
|
||||
<code class="small text-muted d-block text-truncate" title="{{ user.access_key }}">{{ user.access_key }}</code>
|
||||
</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">
|
||||
<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"/>
|
||||
|
||||
@@ -184,5 +184,5 @@ class TestPaginatedObjectListing:
|
||||
assert resp.status_code == 200
|
||||
|
||||
html = resp.data.decode("utf-8")
|
||||
# Should have the JavaScript loading infrastructure
|
||||
assert "loadObjects" in html or "objectsApiUrl" in html
|
||||
# Should have the JavaScript loading infrastructure (external JS file)
|
||||
assert "bucket-detail-main.js" in html
|
||||
|
||||
Reference in New Issue
Block a user