| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 5 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 5 个月前 | ||
| 4 个月前 | ||
| 5 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 5 个月前 | ||
| 1 年前 |
Mirror Management System Documentation
This document describes the mirror management system used in epkg, including its architecture, data flows, and usage instructions.
Directory Structure
/c/epkg/
├── assets/
│ ├── mirrors/ # Mirror configurations
│ │ ├── manual-mirrors.json # Manual mirror configurations
│ │ └── mirrors.json # Final mirror database
│ └── repos/ # Distribution configs
│ ├── ubuntu.yaml # Ubuntu distribution config
│ ├── debian.yaml # Debian distribution config
│ ├── fedora.yaml # Fedora distribution config
│ ├── archlinux.yaml # Arch Linux distribution config
│ ├── alpine.yaml # Alpine distribution config
│ └── *.yaml # Other distribution configs
│
└── scripts/mirror/ # Processing scripts directory
├── *.py # Python processing scripts
├── Makefile # Automation Makefile
├── html-cache/ # HTML and JS-rendered cache
├── lftp-cache/ # LFTP directory listing cache
├── input/ # Downloaded mirror lists
│ ├── mirrors-alpine.txt # Alpine Linux official mirror list
│ ├── mirrors-archlinux.txt # Arch Linux official mirror list
│ ├── mirrors-debian.html # Debian official mirror list
│ ├── mirrors-fedora.html # Fedora official mirror list
│ ├── mirrors-openeuler.html # openEuler official mirror list
│ ├── mirrors-opensuse.html # openSUSE official mirror list
│ └── mirrors-ubuntu.html # Ubuntu official mirror list
├── output/ # Generated files directory
│ ├── official-mirrors.json # Newly discovered mirrors
│ ├── ls-mirrors.json # Directory listings from mirrors
│ ├── probe-mirrors.json # Probed directory information
│ ├── noreach-mirrors.txt # Network unreachable mirrors
│ ├── nocontent-mirrors.txt # Mirrors with no content
│ └── failed-mirrors.log # Log of failed mirror fetches
└── *.txt # Other text files (blacklist, etc.)
Usage Instructions
Prerequisites
# Setup epkg environment in scripts/mirror/
cd scripts/mirror/
epkg env create --root ".eenv" -c debian
# below epkg commands will auto find-use the env at CWD/.eenv
epkg install python3-pip geoip-database chromium-driver lftp
epkg run pip install -r requirements.txt
Alternatively, you can use the Makefile target:
make init
Step-by-Step Workflow
1. Fetch New Mirrors
cd scripts/mirror/
# Discovers mirrors from official distribution sources
# Input: input/mirrors-*.html, input/mirrors-*.txt (downloaded from distribution websites)
# Output: output/official-mirrors.json
epkg run fetch_official_mirrors.py
2. List Directory Contents
cd scripts/mirror/
# Fetches directory listings from discovered mirrors
# Input: output/official-mirrors.json + previous output/ls-mirrors.json + assets/repos/*.yaml
# Output: updated output/ls-mirrors.json
epkg run ls_mirrors.py
3. Probe Unknown Mirrors
cd scripts/mirror/
# Probes mirrors without directory listings
# Input: output/ls-mirrors.json + assets/repos/*.yaml
# Output: output/probe-mirrors.json + output/noreach-mirrors.txt + output/nocontent-mirrors.txt
epkg run probe_dirs.py
4. Update Manual Configuration
ls_mirrors.py will print recommendations for assets/mirrors/manual-mirrors.json:
"http://mirror.example.com":{"cc":"US","ls":["ubuntu","debian"]},
Copy/paste relevant entries to assets/mirrors/manual-mirrors.json:
# Edit manual configuration
vim assets/mirrors/manual-mirrors.json
5. Generate Final Configuration
cd scripts/mirror/
# Merges all data sources into final configuration
# Input: All JSON files + assets/mirrors/manual-mirrors.json + error files
# Output: assets/mirrors/mirrors.json
epkg run merge_mirrors.py
Makefile Automation
A Makefile is provided to automate the pipeline execution. It defines targets for each stage and handles dependencies between them.
Available Targets
cd scripts/mirror/
make help # Show available targets and usage
make all # Run complete pipeline (stages 1-4)
make stage1 # Fetch new mirrors from official sources
make stage2 # List directory contents from discovered mirrors
make stage3 # Probe unknown mirrors for directory structure
make stage4 # Merge all data into final configuration
make init # Create directories and setup epkg environment
make clean-cache # Clean HTML and LFTP cache files
make clean # Clean all generated files (except input/cache files)
Usage Examples
# Run complete pipeline
make all
# Run only specific stages
make stage1
make stage2
# Setup environment and directories
make init
# Clean generated files
make clean
The Makefile uses epkg run for all Python script execution and automatically detects the epkg environment in ./.eenv.
Debugging and Maintenance
Common Debug Commands
cd scripts/mirror/
# Parse a single HTML file for testing
epkg run ls_mirrors.py --parse html-cache/example.com.html
# Check certificate issues
grep -l certificate lftp-cache/*.lftp
# Remove problematic cache files
rm $(grep -l certificate lftp-cache/*.lftp)
# Study directory patterns
rg "=ubuntu" html-cache/*.html
File Inspection Commands
# Check processing files
ls scripts/mirror/output/*.json
ls scripts/mirror/output/*.txt
# Check final output
ls assets/mirrors/*.json
# Check distribution configs
ls assets/repos/*.yaml
# Check downloaded mirror lists
ls scripts/mirror/input/mirrors-*
# Monitor cache usage
du -sh html-cache/ lftp-cache/
Cache Management
cd scripts/mirror/
# Clean HTML cache
rm html-cache/*.html
# Clean LFTP cache
rm lftp-cache/*.lftp
Error Handling
Common Failure Modes
- Network Issues: Timeouts, connection refused, DNS failures
- Content Issues: JavaScript-only sites, custom formats, redirects
- Certificate Problems: Expired/invalid SSL certificates
- Rate Limiting: Server-side request throttling
File-Specific Error Handling
| Error Type | Affected Files | Location | Resolution |
|---|---|---|---|
| Network failures | noreach-mirrors.txt |
scripts/mirror/output/ |
Review and retry |
| Content issues | nocontent-mirrors.txt |
scripts/mirror/output/ |
Manual investigation |
Mitigation Strategies
- Multiple parsing strategies for HTML content
- JavaScript rendering fallback for dynamic sites
- LFTP fallback for HTTP parsing failures
- Comprehensive blacklisting of problematic mirrors
- GeoIP-based country resolution as fallback
Configuration Files
DISTRO_CONFIGS Structure
Located in: assets/repos/*.yaml (one file per distribution)
Each distribution configuration file maps the distribution name to its expected directory structures:
Example assets/repos/ubuntu.yaml:
distro_dirs:
- ubuntu
- ubuntu-ports
- ubuntu-releases
- ubuntu-security
Example assets/repos/debian.yaml:
distro_dirs:
- debian
- debian-security
- debian-multimedia
- debian-backports
Example assets/repos/archlinux.yaml:
distro_dirs:
- archlinux
- archlinux-arm
- archlinuxcn
These configuration files drive the directory filtering logic across all scripts. The distro_dirs values are used to filter mirror directory listings to only include directories that match known distribution patterns.
System Architecture
graph TB
A[External Mirror Sources] --> B[scripts/mirror/fetch_official_mirrors.py]
B --> C[scripts/mirror/output/official-mirrors.json]
C --> D[scripts/mirror/ls_mirrors.py]
D --> E[scripts/mirror/output/ls-mirrors.json]
E --> F[scripts/mirror/probe_dirs.py]
F --> G[scripts/mirror/output/probe-mirrors.json]
F --> H[scripts/mirror/output/noreach-mirrors.txt]
F --> I[scripts/mirror/output/nocontent-mirrors.txt]
J[assets/mirrors/manual-mirrors.json] --> K[scripts/mirror/merge_mirrors.py]
C --> K
E --> K
G --> K
H --> K
I --> K
K --> L[assets/mirrors/mirrors.json]
L --> M[Rust Application]
J --> M
N[assets/repos/*.yaml] --> D
N --> F
N --> K
%% Color coding by file type
style A fill:#f9f9f9,color:#333 %% External sources
style B fill:#e3f2fd,color:#1976d2 %% Python scripts
style D fill:#e3f2fd,color:#1976d2 %% Python scripts
style F fill:#e3f2fd,color:#1976d2 %% Python scripts
style K fill:#e3f2fd,color:#1976d2 %% Python scripts
style C fill:#fff3e0,color:#f57c00 %% JSON processing files
style E fill:#fff3e0,color:#f57c00 %% JSON processing files
style G fill:#fff3e0,color:#f57c00 %% JSON processing files
style H fill:#ffebee,color:#d32f2f %% Error/blacklist files
style I fill:#ffebee,color:#d32f2f %% Error/blacklist files
style J fill:#e8f5e8,color:#388e3c %% Manual config files
style N fill:#e8f5e8,color:#388e3c %% Config files
style L fill:#e1f5fe,color:#0277bd %% Final output
style M fill:#f3e5f5,color:#7b1fa2 %% Rust application
File System Overview
Input Files (External Sources)
| File | Path | Purpose | Format | Source |
|---|---|---|---|---|
mirrors-alpine.txt |
scripts/mirror/input/ |
Alpine Linux official mirror list | Plain text | Downloaded |
mirrors-archlinux.txt |
scripts/mirror/input/ |
Arch Linux official mirror list | Plain text | Downloaded |
mirrors-debian.html |
scripts/mirror/input/ |
Debian official mirror list | HTML | Downloaded |
mirrors-fedora.html |
scripts/mirror/input/ |
Fedora official mirror list | HTML | Downloaded |
mirrors-openeuler.html |
scripts/mirror/input/ |
openEuler official mirror list | HTML | Downloaded |
mirrors-opensuse.html |
scripts/mirror/input/ |
openSUSE official mirror list | HTML | Downloaded |
mirrors-ubuntu.html |
scripts/mirror/input/ |
Ubuntu official mirror list | HTML | Downloaded |
Configuration Files
| File | Path | Purpose | Format | Usage |
|---|---|---|---|---|
ubuntu.yaml |
assets/repos/ |
Ubuntu distribution directory mappings | YAML | Directory filtering |
debian.yaml |
assets/repos/ |
Debian distribution directory mappings | YAML | Directory filtering |
fedora.yaml |
assets/repos/ |
Fedora distribution directory mappings | YAML | Directory filtering |
archlinux.yaml |
assets/repos/ |
Arch Linux distribution directory mappings | YAML | Directory filtering |
alpine.yaml |
assets/repos/ |
Alpine distribution directory mappings | YAML | Directory filtering |
*.yaml |
assets/repos/ |
Other distribution configs | YAML | Directory filtering |
Manual Configuration Files
| File | Path | Purpose | Format | Maintenance |
|---|---|---|---|---|
manual-mirrors.json |
assets/repos/ |
Manually curated mirror configurations | JSON (linewise) | Manual editing |
Intermediate Processing Files
| File | Path | Purpose | Generated By | Used By |
|---|---|---|---|---|
official-mirrors.json |
scripts/mirror/output/ |
Newly discovered mirrors | fetch_official_mirrors.py |
ls_mirrors.py, merge_mirrors.py |
ls-mirrors.json |
scripts/mirror/output/ |
Directory listings from mirrors | ls_mirrors.py |
probe_dirs.py, merge_mirrors.py |
probe-mirrors.json |
scripts/mirror/output/ |
Probed directory information | probe_dirs.py |
merge_mirrors.py |
Blacklist and Error Files
| File | Path | Purpose | Generated By | Used By |
|---|---|---|---|---|
noreach-mirrors.txt |
scripts/mirror/output/ |
Network unreachable mirrors | probe_dirs.py |
merge_mirrors.py |
nocontent-mirrors.txt |
scripts/mirror/output/ |
Mirrors with no content | probe_dirs.py |
merge_mirrors.py |
Final Output Files
| File | Path | Purpose | Format | Used By |
|---|---|---|---|---|
mirrors.json |
assets/repos/ |
Final mirror configuration | JSON (compact) | Rust load_mirrors_for_distro() |
manual-mirrors.json recommendations |
assets/repos/ |
Suggested manual configurations | JSON (linewise) | Rust load_mirrors_for_distro() |
Cache Directories
| Directory | Path | Purpose | Contents |
|---|---|---|---|
html-cache/ |
scripts/mirror/html-cache/ |
HTML and JS-rendered cache | *.html files |
lftp-cache/ |
scripts/mirror/lftp-cache/ |
LFTP directory listing cache | *.lftp files |
Data Processing Pipeline
Stage 1: Mirror Discovery
graph LR
A[Distribution Websites] --> B[scripts/mirror/fetch_official_mirrors.py]
B --> C[Parse HTML/Text]
C --> D[Extract URLs]
D --> F[scripts/mirror/output/official-mirrors.json]
G[mirrors-alpine.txt] <--> B
H[mirrors-archlinux.txt] <--> B
I[mirrors-debian.html] <--> B
J[mirrors-fedora.html] <--> B
K[mirrors-openeuler.html] <--> B
L[mirrors-opensuse.html] <--> B
M[mirrors-ubuntu.html] <--> B
style B fill:#e3f2fd,color:#1976d2
style F fill:#fff3e0,color:#f57c00
style G fill:#f9f9f9,color:#333
style H fill:#f9f9f9,color:#333
style I fill:#f9f9f9,color:#333
style J fill:#f9f9f9,color:#333
style K fill:#f9f9f9,color:#333
style L fill:#f9f9f9,color:#333
style M fill:#f9f9f9,color:#333
File Operations:
- Input:
scripts/mirror/input/mirrors-alpine.txtscripts/mirror/input/mirrors-archlinux.txtscripts/mirror/input/mirrors-debian.htmlscripts/mirror/input/mirrors-fedora.htmlscripts/mirror/input/mirrors-openeuler.htmlscripts/mirror/input/mirrors-opensuse.htmlscripts/mirror/input/mirrors-ubuntu.html
- Output:
scripts/mirror/output/official-mirrors.json - Cache:
scripts/mirror/html-cache/*.html
Stage 2: Directory Listing
graph LR
A[scripts/mirror/output/official-mirrors.json] --> B[scripts/mirror/ls_mirrors.py]
B --> C[HTTP Requests]
C --> D[Parse HTML Directory Listings]
D --> E[Filter by DISTRO_CONFIGS]
E --> F[JavaScript Rendering]
F --> G[LFTP Fallback]
G --> H[scripts/mirror/output/ls-mirrors.json]
I[assets/repos/*.yaml] --> E
style B fill:#e3f2fd,color:#1976d2
style A fill:#fff3e0,color:#f57c00
style H fill:#fff3e0,color:#f57c00
style I fill:#e8f5e8,color:#388e3c
File Operations:
- Input:
scripts/mirror/output/official-mirrors.json- Previous
scripts/mirror/output/ls-mirrors.json assets/repos/*.yaml(distribution configs)
- Output: Updated
scripts/mirror/output/ls-mirrors.json - Cache:
scripts/mirror/html-cache/*.html,scripts/mirror/lftp-cache/*.lftp
Stage 3: Mirror Probing
graph LR
A[scripts/mirror/output/ls-mirrors.json] --> B[scripts/mirror/probe_dirs.py]
B --> C[LFTP Probing]
C --> D[Directory Discovery]
D --> E[Blacklist Generation]
E --> F[scripts/mirror/output/probe-mirrors.json]
E --> H[scripts/mirror/output/noreach-mirrors.txt]
E --> I[scripts/mirror/output/nocontent-mirrors.txt]
J[assets/repos/*.yaml] --> D
style B fill:#e3f2fd,color:#1976d2
style A fill:#fff3e0,color:#f57c00
style F fill:#fff3e0,color:#f57c00
style H fill:#ffebee,color:#d32f2f
style I fill:#ffebee,color:#d32f2f
style J fill:#e8f5e8,color:#388e3c
File Operations:
- Input:
scripts/mirror/output/ls-mirrors.jsonassets/repos/*.yaml(distribution configs)
- Output:
scripts/mirror/output/probe-mirrors.jsonscripts/mirror/output/noreach-mirrors.txtscripts/mirror/output/nocontent-mirrors.txt
- Cache:
scripts/mirror/lftp-cache/*.lftp
Stage 4: Data Merging
graph LR
A[scripts/mirror/output/official-mirrors.json] --> F[scripts/mirror/merge_mirrors.py]
B[scripts/mirror/output/ls-mirrors.json] --> F
C[scripts/mirror/output/probe-mirrors.json] --> F
E[scripts/mirror/output/no*-mirrors.txt] --> F
F --> G[Data Deduplication]
G --> H[Country Code Resolution]
H --> I[Field Compaction]
I --> J[assets/mirrors/mirrors.json]
style F fill:#e3f2fd,color:#1976d2
style A fill:#fff3e0,color:#f57c00
style B fill:#fff3e0,color:#f57c00
style C fill:#fff3e0,color:#f57c00
style E fill:#ffebee,color:#d32f2f
style J fill:#e1f5fe,color:#0277bd
File Operations:
- Input:
scripts/mirror/output/official-mirrors.jsonscripts/mirror/output/ls-mirrors.jsonscripts/mirror/output/probe-mirrors.jsonscripts/mirror/output/noreach-mirrors.txtscripts/mirror/output/nocontent-mirrors.txt
- Output:
assets/mirrors/mirrors.json
File Type Color Legend
| Color | File Type | Examples |
|---|---|---|
| 🔵 Blue | Python Scripts | fetch_official_mirrors.py, ls_mirrors.py, probe_dirs.py, merge_mirrors.py |
| 🟠 Orange | JSON Processing Files | official-mirrors.json, ls-mirrors.json, probe-mirrors.json |
| 🔴 Red | Error/Blacklist Files | noreach-mirrors.txt, nocontent-mirrors.txt |
| 🟢 Green | Configuration Files | manual-mirrors.json, *.yaml |
| 🟦 Light Blue | Final Output | mirrors.json, recommendation for manual-mirrors.json |
| ⚪ Gray | External Sources | mirrors-*.html, mirrors-*.txt |
| 🟣 Purple | Applications | Rust Application |
Input File Locations
# Downloaded mirror lists (complete list)
scripts/mirror/input/mirrors-alpine.txt # Alpine Linux mirrors
scripts/mirror/input/mirrors-archlinux.txt # Arch Linux mirrors
scripts/mirror/input/mirrors-debian.html # Debian mirrors
scripts/mirror/input/mirrors-fedora.html # Fedora mirrors
scripts/mirror/input/mirrors-openeuler.html # openEuler mirrors
scripts/mirror/input/mirrors-opensuse.html # openSUSE mirrors
scripts/mirror/input/mirrors-ubuntu.html # Ubuntu mirrors
# Distribution configuration files
assets/repos/ubuntu.yaml # Ubuntu directory mappings
assets/repos/debian.yaml # Debian directory mappings
assets/mirrors/fedora.yaml # Fedora directory mappings
assets/repos/archlinux.yaml # Arch Linux directory mappings
assets/mirrors/alpine.yaml # Alpine directory mappings
assets/repos/*.yaml # Other distribution configs
Processing File Locations
# Core processing files
scripts/mirror/output/official-mirrors.json # Stage 1 output
scripts/mirror/output/ls-mirrors.json # Stage 2 output
scripts/mirror/output/probe-mirrors.json # Stage 3 output
# Error tracking files
scripts/mirror/output/noreach-mirrors.txt # Network failures
scripts/mirror/output/nocontent-mirrors.txt # Content failures
Final Output Locations
# Production files
assets/mirrors/mirrors.json # Final mirror database
Cache and Log Locations
# Cache directories
scripts/mirror/html-cache/ # HTML and JS-rendered cache files
scripts/mirror/lftp-cache/ # LFTP directory listing cache files
Mirror Data Schema
Primary Mirror Object
{
"https://mirror.example.com": {
"cc": "US", // Country code
"top": "ubuntu", // top level distribution, conflicts with 'ls' field
"ls": ["ubuntu", "debian"], // Listed directories
"p": 3, // Protocol support (HTTP|HTTPS|RSYNC)
"bw": 1000, // Bandwidth (Mbps)
"i2": 1 // Internet2 connection
}
}
Field Mappings
| Full Name | Compact | Type | Description |
|---|---|---|---|
country_code |
cc |
String | ISO 3166-1 alpha-2 country code |
distros |
top |
Array | top level operating system |
distro_dirs |
ls |
Array | Distribution-specific directories |
ls |
ls |
Array | Directories found via listing |
probe_dirs |
ls |
Array | Directories found via probing |
top_level |
top |
Boolean | Mirror serves from root path |
protocols |
p |
Integer | Bitmask for supported protocols |
bandwidth |
bw |
Integer | Bandwidth in Mbps |
internet2 |
i2 |
Boolean | Internet2 high-speed connection |
Protocol Support Flags
| Protocol | Bit | Value | Description |
|---|---|---|---|
| HTTP | 0 | 1 | Standard HTTP access |
| HTTPS | 1 | 2 | Encrypted HTTPS access |
| RSYNC | 2 | 4 | RSYNC protocol support |
Examples:
p: 1= HTTP onlyp: 2= HTTPS onlyp: 3= HTTP + HTTPSp: 7= HTTP + HTTPS + RSYNC
Rust Integration
Mirror Loading Architecture
graph TB
A[load_mirrors_for_distro] --> B[load_primary_mirrors]
A --> C[load_and_merge_manual_mirrors]
A --> D[convert_mirror_data_structure]
A --> E[apply_distro_filtering]
C --> F[merge_single_manual_mirror]
G[assets/mirrors/mirrors.json] --> B
H[assets/mirrors/manual-mirrors.json] --> C
E --> I[Filtered Mirror Collection]
style A fill:#e3f2fd,color:#1976d2
style B fill:#e3f2fd,color:#1976d2
style C fill:#e3f2fd,color:#1976d2
style D fill:#e3f2fd,color:#1976d2
style E fill:#e3f2fd,color:#1976d2
style F fill:#e3f2fd,color:#1976d2
style G fill:#e1f5fe,color:#0277bd
style H fill:#e8f5e8,color:#388e3c
style I fill:#f3e5f5,color:#7b1fa2
Function Responsibilities
| Function | Purpose | Input File Path | Output |
|---|---|---|---|
load_primary_mirrors |
Load main mirror data | assets/mirrors/mirrors.json |
Raw mirror HashMap |
load_and_merge_manual_mirrors |
Merge manual overrides | assets/mirrors/manual-mirrors.json |
Updated HashMap |
merge_single_manual_mirror |
Merge individual mirror | Single mirror data | Updated entry |
convert_mirror_data_structure |
Transform data structure | Raw HashMap | Processed HashMap |
apply_distro_filtering |
Filter by distribution | Processed HashMap + filter | Filtered HashMap |