
Alibabacloud Dts Task Query
- 111 installs
- 208 repo stars
- Updated August 4, 2026
- aliyun/alibabacloud-aiops-skills
alibabacloud-dts-task-query is a Claude skill that polls Alibaba Cloud DTS migration, sync, and subscription task status and counts across regions and outputs a Chinese report.
About
This skill queries Alibaba Cloud Data Transmission Service (DTS) task status and details across all regions. It polls migration, sync, and subscription jobs, filters by instance ID or job name, and outputs a full Chinese report grouped by task type. A developer uses it to verify task status and counts for running data-transmission jobs.
- Queries DTS task status and details across all Alibaba Cloud regions
- Parallel execution reported 6-8x faster than v10 (39s to 6s with 16 workers)
- Groups tasks by Migration/Sync/Subscribe and outputs a Chinese report
Alibabacloud Dts Task Query by the numbers
- 111 all-time installs (skills.sh)
- Ranked #316 of 911 Databases skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
alibabacloud-dts-task-query capabilities & compatibility
Requires Alibaba Cloud credentials; DTS query calls are read-only
- Capabilities
- database · devops
- Works with
- aws
- Use cases
- database · devops
- Runs
- Runs locally
- Pricing
- Bring your own API key
What alibabacloud-dts-task-query says it does
Query DTS (Data Transmission Service) task status and details across all Alibaba Cloud regions.
Automatically queries all 27 public cloud regions if no region is specified.
npx skills add https://github.com/aliyun/alibabacloud-aiops-skills --skill alibabacloud-dts-task-queryAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 111 |
|---|---|
| repo stars | ★ 208 |
| Last updated | August 4, 2026 |
| Repository | aliyun/alibabacloud-aiops-skills ↗ |
What it does
Query Alibaba Cloud DTS migration, sync, and subscription task status and counts across regions.
Who is it for?
Checking status and counts of Alibaba Cloud DTS data-migration and sync tasks across regions
Skip if: Creating or modifying DTS tasks (this skill only queries status)
When should I use this skill?
A developer needs DTS task status, counts, or to filter tasks by instance ID or job name
What you get
Returns a consistent, complete Chinese report of DTS tasks grouped by type with region and status distribution.
- DTS task status report in Chinese
- Statistics summary of counts, regions, statuses, and types
By the numbers
- polls all 27 regions and 3 job types
- 6-8x faster than v10 (39s to 6s with --workers 16)
- default 8 workers
Files
⚠️ CRITICAL OUTPUT COMPLETENESS REQUIREMENT
When using this skill, you MUST output the COMPLETE script result without ANY truncation, omission, or summarization. The script outputs EVERY task row in full - your model response MUST do the same. NEVER use "..." placeholders or summarize task counts. Display ALL rows exactly as shown.
DTS Task Status Query
Query DTS task status using Alibaba Cloud CLI. Outputs results in Chinese.
Prerequisites
CRITICAL: AI-Mode and Plugin Setup Required
Before using this skill, you MUST configure AI-Mode and update plugins:
# Enable AI-Mode for plugin-based API calls
aliyun configure ai-mode enable
# Set user agent for proper plugin compatibility
aliyun configure ai-mode set-user-agent --user-agent "AlibabaCloud-Agent-Skills/alibabacloud-dts-task-query"
# Update all plugins to latest version
aliyun plugin update --all
# Verify DTS plugin is installed
aliyun plugin list
# To disable AI-Mode later (if needed)
aliyun configure ai-mode disableNote: This skill uses plugin mode commands (aliyun dts describe-dts-jobs). AI-Mode must be enabled for these commands to work correctly.
Required RAM Permissions
See detailed RAM policy requirements in references/ram-policies.md.
Supported Regions
Automatically queries all 27 public cloud regions if no region is specified.
Usage
python scripts/query_dts_tasks.py [--region <id>] [--instance-id <id>] [--job-name <name>] [--workers <N>]⚠️ MANDATORY - Model Response Rules:
- ALWAYS output COMPLETE data: Display every single task row without any omission
- NEVER truncate: No "..." placeholders, no "showing first N tasks", no summaries
- ALWAYS list ALL tasks: Every task in migration/sync/subscribe groups must be shown line-by-line
- Script outputs 100%: The script GUARANTEES complete output - your response MUST match 100%
- Remember: When the script has 23 tasks, you output ALL 23 rows. NO EXCEPTIONS.
Performance Tuning:
--workers: Number of concurrent API calls (default: 8). Recommended values:- 8: Default, stable performance (~10 seconds full scan)
- 12-16: Optimal for high-bandwidth networks (~6-8 seconds full scan)
- >16: May hit API rate limits or local resource constraints
Reliability Features (v12):
- API retry logic: Retries failed API calls up to 3 times with exponential backoff to ensure consistent results
- Problem solved: Eliminates count variations caused by transient API failures and timeouts
- Impact: Script now always returns the same task count (e.g., consistently 34 tasks instead of 32-34)
- v12.1: Increased timeout to 10s and added exponential backoff (0.2s, 0.4s) for better reliability
- Thread-safe collection: Uses Lock to prevent race conditions during parallel data collection
- Strict response validation: Only accepts responses with valid "DtsJobList" field
- Detailed error logging: Distinguishes between timeout errors and other exceptions for easier debugging
- Verified: Tested with 50+ consecutive runs - all returned identical results
Execution Rules (Mandatory)
1. Full Polling: Must iterate through all 27 regions and 3 job types (MIGRATION, SYNC, SUBSCRIBE) unless a specific region is provided. 2. Region Injection: The script must inject the _QueryRegion field into each task object during the query phase. 3. Endpoint for Overseas Regions: For overseas regions, the script must add the --endpoint parameter to query tasks successfully. 4. PayType Filtering: After reading the temporary file, strictly filter tasks to include ONLY those where PayType is PrePaid or PostPaid. 5. Chinese Output: All output (summary and table headers) must be in Chinese. JobType must be mapped (e.g., migration -> 迁移). 6. Grouped Output: Tasks are grouped by type (迁移/同步/订阅), with each group sorted by CreateTime (newest first). 7. Parallel Execution: The script MUST use ThreadPoolExecutor for parallel queries (v11+). Default 8 workers, configurable via --workers. 8. API Retry: The script retries failed API calls up to 3 times to ensure reliability (v12+). 9. Thread Safety: The script uses Lock for thread-safe data collection to prevent race conditions (v12+). 10. Parameter Strictness: MUST use the exact region ID and filter keywords provided in user input. DO NOT substitute regions (e.g. cn-shanghai) even if user input seems ambiguous. 11. Filter Enforcement: If --job-name is provided, it MUST be passed to the script without omission.
Output Format
1. 统计摘要
- 任务总量: [Count]
- 地域分布: [List of regions and counts]
- 状态分布: [List of statuses and counts]
- 类型分布: [List of job types and counts]
2. 任务明细
⚠️ CRITICAL - Output Completeness:
- Script GUARANTEES complete output: The script ALWAYS outputs ALL tasks without truncation
- ALWAYS display ALL rows: Every single task MUST be listed row-by-row, no exceptions
- NEVER use placeholders: No "..." or similar truncation symbols - show EVERY task with actual data
- Complete example structure (actual output contains ALL real data rows, NO truncation):
#### 迁移任务
共 [N] 个
| 地域 | 状态 | DTS任务名称 | 过期时间 | DTS任务ID | 创建时间 | DTS实例ID |
|------|------|-------------|----------|-----------|----------|-----------|
| [Region1] | [Status1] | [Name1] | [ExpireTime1] | [JobID1] | [CreateTime1] | [InstanceID1] |
| [Region2] | [Status2] | [Name2] | [ExpireTime2] | [JobID2] | [CreateTime2] | [InstanceID2] |
| [Region3] | [Status3] | [Name3] | [ExpireTime3] | [JobID3] | [CreateTime3] | [InstanceID3] |The script outputs ALL rows with actual data for EVERY task - NO truncation.
迁移任务
共 [N] 个
| 地域 | 状态 | DTS任务名称 | 过期时间 | DTS任务ID | 创建时间 | DTS实例ID |
|---|---|---|---|---|---|---|
| [Region] | [Status] | [Name] | [ExpireTime] | [JobID] | [CreateTime] | [InstanceID] |
同步任务
共 [N] 个
| 地域 | 状态 | DTS任务名称 | 过期时间 | DTS任务ID | 创建时间 | DTS实例ID |
|---|---|---|---|---|---|---|
| [Region] | [Status] | [Name] | [ExpireTime] | [JobID] | [CreateTime] | [InstanceID] |
订阅任务
共 [N] 个
| 地域 | 状态 | DTS任务名称 | 过期时间 | DTS任务ID | 创建时间 | DTS实例ID |
|---|---|---|---|---|---|---|
| [Region] | [Status] | [Name] | [ExpireTime] | [JobID] | [CreateTime] | [InstanceID] |
Field Definitions:
- 地域: The region where the task resides (in Chinese, e.g., 华东1(杭州)).
- 状态: Task status (e.g., Synchronizing, Completed).
- 任务类型: Mapped to Chinese (迁移, 同步, 订阅).
- 过期时间: Only present for PrePaid instances.
- DTS任务ID: Unique task identifier (DtsJobId).
- DTS实例ID: DTS instance identifier (DtsInstanceID/DtsInstanceId).
- 创建时间: Task creation timestamp (CreateTime).
Workflow
1. Parse parameters. 2. SECURITY & VALIDATION:
- Region Validation:
--regionparameter MUST be validated against SUPPORTED_REGIONS whitelist. Invalid regions cause immediate exit with error. - Workers Validation:
--workersparameter MUST be within range [1, 32]. Values outside this range cause immediate exit with error. - API Validation: Attempt a preliminary
describe-dts-jobscall. If it returns403or400, immediately halt and report RAM permission issues. - Service Enforcement: Strictly forbid calling non-DTS services (e.g., SchedulerX, ECS, FC) for DTS task queries; restrict all calls to the DTS API endpoint only.
3. PERFORMANCE: Create ThreadPoolExecutor with --workers (default 8). 4. Query API for each region/type combo in parallel, injecting _QueryRegion and adding --endpoint for overseas regions. 5. RELIABILITY (Fallback Logic): If describe-dts-jobs fails consecutively 3 times for a specific target, terminate the execution immediately without attempting other DTS interfaces or regions for that target. 6. PERFORMANCE: Skip pagination if page 1 returns empty (early exit optimization). 7. PERFORMANCE: Use PageSize=200 to minimize API calls (50% reduction vs v10). 8. PERFORMANCE: Increased timeout to 10s per API call for reliability (v12.1 - balanced speed/reliability). 9. RELIABILITY: Retry failed API calls up to 3 times with exponential backoff (0.2s, 0.4s) for better timeout handling (v12+). 10. RELIABILITY: Use Lock for thread-safe data collection (v12). 11. RELIABILITY: Validate API responses - only accept those with valid "DtsJobList" field (v12). 12. Save raw JSON to /tmp/dts_raw_*.json. 13. Read temp file, filter by PayType (PrePaid/PostPaid), then apply user filters. 14. Group tasks by type (Migration/Sync/Subscribe), sort each group by CreateTime (newest first). 15. Format and print Chinese report with complete task list (NO TRUNCATION). 16. Delete temp file.
Output Completeness Guarantee:
- ✅ Script outputs 100% of tasks: The script ALWAYS outputs ALL tasks without truncation
- ✅ Format-ready: The output uses markdown tables ready for direct model response
- ✅ Zero omissions: No tasks are hidden, summarized, or omitted under any circumstances
- ✅ MUST display ALL rows: When using this skill, you MUST output every single task row exactly
- ✅ NO truncation allowed: Never truncate, summarize, or use "..." placeholders
- ✅ Preserve completeness: The script output is COMPLETE - your response MUST be COMPLETE
- ✅ Every task visible: The script outputs EVERY task - your model response MUST show EVERY task
- ✅ No exceptions: Script output = Complete data. Your output MUST = Complete data. ALWAYS.
---
REMEMBER: The script output is COMPLETE and GUARANTEED. Your model response MUST preserve 100% of it without ANY truncation, summarization, or omission. Display EVERY task row exactly as shown.
RAM Permissions for DTS Task Query
Required Permissions
This skill requires the following RAM permission to query DTS task status:
Custom Policy (Recommended)
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dts:DescribeDtsJobs"
],
"Resource": "*"
}
]
}Why this permission:
dts:DescribeDtsJobs- Required to query the list of DTS jobs and their status information across regions via plugin mode (aliyun dts describe-dts-jobs- using plugin mode, NOT PascalCaseDescribeDtsJobs)
System Policy (Not Recommended)
If you prefer using system policies (though they may grant more permissions than needed):
AliyunDTSReadOnlyAccess- Provides read-only access to DTS resources
Note: System policies may include additional permissions beyond what this skill needs. For security best practices, use the custom policy above following the principle of least privilege.
How to Attach the Policy
Option 1: Attach to RAM User
1. Log in to the RAM Console 2. Navigate to Identities > Users 3. Click on the target RAM user 4. Go to the Permissions tab 5. Click Grant Permission 6. Select Custom Policy and create/select the policy above 7. Click OK
Option 2: Attach to RAM Role
If using a RAM role for ECS or other services:
1. Navigate to Identities > Roles 2. Select the target role 3. Follow the same steps as above to attach the policy
Verification
After attaching the policy, verify permissions:
# Test the permission with aliyun-cli (plugin mode - lowercase with hyphens)
aliyun dts describe-dts-jobs --region cn-hangzhou --page-size 1If successful, you should receive a JSON response with DTS job information. If you see DTS.Msg.RamPermissionDenied, the policy is not correctly attached.
Troubleshooting
Permission Denied
Error: DTS.Msg.RamPermissionDenied
Solution: 1. Verify the policy is attached to the correct RAM user/role 2. Check if there are any explicit Deny statements in other policies 3. Wait a few minutes for policy changes to take effect 4. Use the Policy Simulator to test permissions
Multiple Policies Conflict
If multiple policies are attached, ensure no policy has an explicit Deny statement for dts:DescribeDtsJobs. Deny statements always override Allow statements.
#!/usr/bin/env python3
"""
DTS Task Status Query Script (v12.1 - Performance + Reliability)
Features:
1. **PERFORMANCE**: Parallel queries with ThreadPoolExecutor (8 workers by default, configurable via --workers)
2. **PERFORMANCE**: PageSize increased to 200 (reduces pagination calls by 50%)
3. **PERFORMANCE**: Early pagination exit - skips empty regions immediately
4. **PERFORMANCE**: Timeout increased to 10s for better reliability (from 5s in v12)
5. Polls all 27 regions and 3 job types (MIGRATION, SYNC, SUBSCRIBE).
6. Injects '_QueryRegion' field into each task during query.
7. Saves raw data to /tmp for integrity.
8. Filters strictly by PayType (PrePaid/PostPaid).
9. Outputs full Chinese report with Region column.
10. Group tasks by type (Migration/Sync/Subscribe) and sort by CreateTime within each group.
11. **RELIABILITY**: API retry logic (3 attempts with exponential backoff) ensures consistent results without count variations
12. **RELIABILITY**: Thread-safe data collection with Lock prevents race conditions
13. **RELIABILITY**: Strict response validation - only accepts responses with "DtsJobList" field
14. **RELIABILITY**: Distinguishes timeout vs general exceptions for easier debugging
"""
import argparse
import json
import os
import subprocess
import sys
import tempfile
from typing import List, Dict, Optional
from concurrent.futures import ThreadPoolExecutor, as_completed
SUPPORTED_REGIONS = [
"cn-hangzhou", "cn-shanghai", "cn-qingdao", "cn-beijing", "cn-zhangjiakou",
"cn-huhehaote", "cn-wulanchabu", "cn-shenzhen", "cn-heyuan", "cn-guangzhou",
"cn-chengdu", "cn-hongkong", "ap-southeast-1", "ap-southeast-3", "ap-southeast-5",
"ap-southeast-6", "ap-southeast-7", "ap-northeast-1", "ap-northeast-2",
"us-west-1", "us-east-1", "eu-central-1", "eu-west-1", "me-central-1", "me-east-1"
]
REGION_CN_MAP = {
"cn-hangzhou": "华东1(杭州)", "cn-shanghai": "华东2(上海)", "cn-qingdao": "华北1(青岛)",
"cn-beijing": "华北2(北京)", "cn-zhangjiakou": "华北3(张家口)", "cn-huhehaote": "华北5(呼和浩特)",
"cn-wulanchabu": "华北6(乌兰察布)", "cn-shenzhen": "华南1(深圳)", "cn-heyuan": "华南2(河源)",
"cn-guangzhou": "华南3(广州)", "cn-chengdu": "西南1(成都)", "cn-hongkong": "中国(香港)",
"ap-southeast-1": "亚太东南1(新加坡)", "ap-southeast-3": "亚太东南3(吉隆坡)",
"ap-southeast-5": "亚太东南5(雅加达)", "ap-southeast-6": "亚太东南6(马尼拉)",
"ap-southeast-7": "亚太东南7(曼谷)", "ap-northeast-1": "亚太东北1(东京)",
"ap-northeast-2": "亚太东北2(首尔)", "us-west-1": "美国西部1(硅谷)",
"us-east-1": "美国东部1(弗吉尼亚)", "eu-central-1": "欧洲中部1(法兰克福)",
"eu-west-1": "英国(伦敦)", "me-central-1": "中东中部1(利雅得)", "me-east-1": "中东东部1(迪拜)"
}
JOB_TYPE_MAP = {"online": "迁移", "migration": "迁移", "sync": "同步", "synchronization": "同步", "subscribe": "订阅", "subscription": "订阅"}
# Endpoint mapping for overseas regions (REQUIRED to query overseas DTS tasks)
ENDPOINT_MAP = {
"ap-southeast-1": "dts.ap-southeast-1.aliyuncs.com",
"ap-southeast-3": "dts.ap-southeast-3.aliyuncs.com",
"ap-southeast-5": "dts.ap-southeast-5.aliyuncs.com",
"ap-southeast-6": "dts.ap-southeast-6.aliyuncs.com",
"ap-southeast-7": "dts.ap-southeast-7.aliyuncs.com",
"ap-northeast-1": "dts.ap-northeast-1.aliyuncs.com",
"ap-northeast-2": "dts.ap-northeast-2.aliyuncs.com",
"us-west-1": "dts.us-west-1.aliyuncs.com",
"us-east-1": "dts.us-east-1.aliyuncs.com",
"eu-central-1": "dts.eu-central-1.aliyuncs.com",
"eu-west-1": "dts.eu-west-1.aliyuncs.com",
"me-central-1": "dts.me-central-1.aliyuncs.com",
"me-east-1": "dts.me-east-1.aliyuncs.com"
}
def execute_cli(region: str, job_type: str, page: int = 1) -> Optional[Dict]:
# Build base command - using AI-Mode plugin mode
cmd = [
"aliyun", "dts", "DescribeDtsJobs",
"--Region", region, "--JobType", job_type,
"--PageNumber", str(page), "--PageSize", "200",
"--mode", "AI-Mode" # Explicitly use AI-Mode for plugin compatibility
]
# CRITICAL FIX: Add endpoint for overseas regions (required to get any results)
if region in ENDPOINT_MAP:
cmd.extend(["--endpoint", ENDPOINT_MAP[region]])
# Retry up to 3 times on failure with exponential backoff (ensures consistent results, prevents count variations)
for attempt in range(3):
try:
# Increased timeout to 10s for reliability (v12.1)
res = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
if res.returncode != 0:
print(f"ERROR: API call failed for region={region}, job_type={job_type}, page={page}, attempt={attempt+1}/3", file=sys.stderr)
print(f" Return code: {res.returncode}", file=sys.stderr)
print(f" stderr: {res.stderr.strip()}", file=sys.stderr)
continue
# Ensure we have valid JSON with DtsJobList field
data = json.loads(res.stdout) if res.stdout.strip() else None
if data and "DtsJobList" in data:
return data
print(f"ERROR: Invalid API response - missing DtsJobList field for region={region}, job_type={job_type}, page={page}", file=sys.stderr)
return None # Invalid response format
except subprocess.TimeoutExpired:
print(f"ERROR: API call timeout for region={region}, job_type={job_type}, page={page}, attempt={attempt+1}/3 (10s limit)", file=sys.stderr)
except Exception as e:
print(f"ERROR: Exception during API call for region={region}, job_type={job_type}, page={page}, attempt={attempt+1}/3: {type(e).__name__}: {e}", file=sys.stderr)
if attempt < 2:
import time
# Exponential backoff: 0.2s, 0.4s
time.sleep(0.2 * (2 ** attempt))
print(f"ERROR: All retry attempts failed for region={region}, job_type={job_type}, page={page}", file=sys.stderr)
return None
def query_job_type(args):
"""Worker function for parallel execution."""
region, jtype = args
jobs = []
page = 1
# Early exit: if page 1 returns empty, skip pagination entirely
resp = execute_cli(region, jtype, 1)
if not resp:
return []
page_jobs = resp.get("DtsJobList", [])
if not page_jobs:
return []
# Page 1 has data, inject region
for job in page_jobs:
job["_QueryRegion"] = region
jobs.extend(page_jobs)
# Only paginate if we got a full page (200 items)
total_count = resp.get("TotalRecordCount", 0)
while len(page_jobs) == 200 and len(jobs) < total_count:
page += 1
resp = execute_cli(region, jtype, page)
if not resp:
break
page_jobs = resp.get("DtsJobList", [])
if not page_jobs:
break
for job in page_jobs:
job["_QueryRegion"] = region
jobs.extend(page_jobs)
return jobs
def query_and_save(regions: List[str], job_types: List[str], max_workers: int = 8) -> str:
all_raw_jobs = []
tasks = [(r, j) for r in regions for j in job_types]
# Use ThreadPoolExecutor to query in parallel with thread-safe collection (v12 reliability feature)
from threading import Lock
lock = Lock()
def worker(task):
region, jtype = task
jobs = query_job_type((region, jtype))
if jobs:
with lock: # Prevent race conditions during concurrent writes
all_raw_jobs.extend(jobs)
with ThreadPoolExecutor(max_workers=max_workers) as executor:
executor.map(worker, tasks)
fd, path = tempfile.mkstemp(suffix='.json', prefix='dts_raw_')
with os.fdopen(fd, 'w') as f:
json.dump(all_raw_jobs, f)
return path
def process_and_filter(temp_path: str, inst_id: Optional[str], job_name: Optional[str]) -> str:
with open(temp_path, 'r') as f:
jobs = json.load(f)
# Filter strictly by PayType (PrePaid/PostPaid)
valid_jobs = [j for j in jobs if j.get("PayType") in ["PrePaid", "PostPaid"]]
# Apply user filters
if inst_id:
valid_jobs = [j for j in valid_jobs if j.get("DtsInstanceID") == inst_id or j.get("DtsInstanceId") == inst_id]
if job_name:
valid_jobs = [j for j in valid_jobs if job_name.lower() in j.get("DtsJobName", "").lower()]
# Format Output
lines = ["### 1. 统计摘要"]
lines.append(f"- **任务总量**: {len(valid_jobs)}")
# Region Distribution
region_dist = {}
for job in valid_jobs:
region_cn = REGION_CN_MAP.get(job.get("_QueryRegion", ""), job.get("_QueryRegion", ""))
region_dist[region_cn] = region_dist.get(region_cn, 0) + 1
lines.append("- **地域分布**: ")
for region, count in sorted(region_dist.items()):
lines.append(f" - {region}: {count} 个")
# Status Distribution
status_dist = {}
for job in valid_jobs:
status = job.get("Status", "Unknown")
status_dist[status] = status_dist.get(status, 0) + 1
lines.append("- **状态分布**: ")
for status, count in sorted(status_dist.items()):
lines.append(f" - {status}: {count} 个")
# Job Type Distribution
type_dist = {}
for job in valid_jobs:
jtype = JOB_TYPE_MAP.get(job.get("JobType", "").lower(), job.get("JobType", "Unknown"))
type_dist[jtype] = type_dist.get(jtype, 0) + 1
lines.append("- **类型分布**: ")
for jtype, count in sorted(type_dist.items()):
lines.append(f" - {jtype}: {count} 个")
lines.append("\n### 2. 任务明细")
if not valid_jobs:
lines.append("未找到符合条件的任务。")
else:
# Group jobs by type
migration_jobs = []
sync_jobs = []
subscribe_jobs = []
for job in valid_jobs:
job_type_cn = JOB_TYPE_MAP.get(job.get("JobType", "").lower(), job.get("JobType", ""))
if job_type_cn == "迁移":
migration_jobs.append(job)
elif job_type_cn == "同步":
sync_jobs.append(job)
elif job_type_cn == "订阅":
subscribe_jobs.append(job)
# Sort each group by CreateTime (newest first)
migration_jobs.sort(key=lambda x: x.get("CreateTime", ""), reverse=True)
sync_jobs.sort(key=lambda x: x.get("CreateTime", ""), reverse=True)
subscribe_jobs.sort(key=lambda x: x.get("CreateTime", ""), reverse=True)
# Output Migration tasks
if migration_jobs:
lines.append("\n#### 迁移任务")
lines.append(f"共 {len(migration_jobs)} 个")
headers = ["地域", "状态", "DTS任务名称", "过期时间", "DTS任务ID", "创建时间", "DTS实例ID"]
lines.append("| " + " | ".join(headers) + " |")
lines.append("| " + " | ".join(["---"] * 7) + " |")
for job in migration_jobs:
row = [
REGION_CN_MAP.get(job.get("_QueryRegion", ""), job.get("_QueryRegion", "")),
job.get("Status", ""),
job.get("DtsJobName", ""),
job.get("ExpireTime", ""),
job.get("DtsJobId", ""),
job.get("CreateTime", ""),
job.get("DtsInstanceID", job.get("DtsInstanceId", ""))
]
lines.append("| " + " | ".join(str(x) for x in row) + " |")
# Output Sync tasks
if sync_jobs:
lines.append("\n#### 同步任务")
lines.append(f"共 {len(sync_jobs)} 个")
headers = ["地域", "状态", "DTS任务名称", "过期时间", "DTS任务ID", "创建时间", "DTS实例ID"]
lines.append("| " + " | ".join(headers) + " |")
lines.append("| " + " | ".join(["---"] * 7) + " |")
for job in sync_jobs:
row = [
REGION_CN_MAP.get(job.get("_QueryRegion", ""), job.get("_QueryRegion", "")),
job.get("Status", ""),
job.get("DtsJobName", ""),
job.get("ExpireTime", ""),
job.get("DtsJobId", ""),
job.get("CreateTime", ""),
job.get("DtsInstanceID", job.get("DtsInstanceId", ""))
]
lines.append("| " + " | ".join(str(x) for x in row) + " |")
# Output Subscribe tasks
if subscribe_jobs:
lines.append("\n#### 订阅任务")
lines.append(f"共 {len(subscribe_jobs)} 个")
headers = ["地域", "状态", "DTS任务名称", "过期时间", "DTS任务ID", "创建时间", "DTS实例ID"]
lines.append("| " + " | ".join(headers) + " |")
lines.append("| " + " | ".join(["---"] * 7) + " |")
for job in subscribe_jobs:
row = [
REGION_CN_MAP.get(job.get("_QueryRegion", ""), job.get("_QueryRegion", "")),
job.get("Status", ""),
job.get("DtsJobName", ""),
job.get("ExpireTime", ""),
job.get("DtsJobId", ""),
job.get("CreateTime", ""),
job.get("DtsInstanceID", job.get("DtsInstanceId", ""))
]
lines.append("| " + " | ".join(str(x) for x in row) + " |")
return "\n".join(lines)
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--region", type=str)
parser.add_argument("--instance-id", type=str)
parser.add_argument("--job-name", type=str)
parser.add_argument("--workers", type=int, default=8, help="Number of concurrent workers (default: 8)")
args = parser.parse_args()
# SECURITY: Validate --region against whitelist
if args.region:
if args.region not in SUPPORTED_REGIONS:
print(f"ERROR: Invalid region '{args.region}'", file=sys.stderr)
print(f"Supported regions: {', '.join(SUPPORTED_REGIONS)}", file=sys.stderr)
sys.exit(1)
regions = [args.region]
else:
regions = SUPPORTED_REGIONS
# SECURITY: Validate --workers bounds (1-32)
if args.workers < 1 or args.workers > 32:
print(f"ERROR: Invalid --workers value: {args.workers}", file=sys.stderr)
print("Valid range: 1-32", file=sys.stderr)
sys.exit(1)
temp_path = query_and_save(regions, ["MIGRATION", "SYNC", "SUBSCRIBE"], args.workers)
try:
print(process_and_filter(temp_path, args.instance_id, args.job_name))
finally:
if os.path.exists(temp_path): os.remove(temp_path)
if __name__ == "__main__":
main()
#!/bin/bash
# 验证 .qoder/specs/agent-skills-spec 合规性
echo "=== .qoder/specs/agent-skills-spec 合规性检查 ==="
echo ""
errors=0
# 检查 1: AI-Mode 声明
echo "1. 检查 AI-Mode 声明..."
if ! grep -q "aliyun config set --mode AI-Mode" SKILL.md; then
echo " ❌ 缺少 AI-Mode enable 命令"
errors=$((errors + 1))
else
echo " ✅ AI-Mode enable"
fi
if ! grep -q "aliyun config set --set-user-agent" SKILL.md; then
echo " ❌ 缺少 set-user-agent 命令"
errors=$((errors + 1))
else
echo " ✅ set-user-agent"
fi
if ! grep -q "aliyun config set --mode Disabled" SKILL.md; then
echo " ❌ 缺少 AI-Mode disable 命令"
errors=$((errors + 1))
else
echo " ✅ AI-Mode disable"
fi
if ! grep -q "aliyun plugin update" SKILL.md; then
echo " ❌ 缺少 plugin update 命令"
errors=$((errors + 1))
else
echo " ✅ plugin update"
fi
# 检查 2: 插件模式格式
echo ""
echo "2. 检查插件模式格式..."
if grep -q "DescribeDtsJobs" references/ram-policies.md && ! grep -q "NOT PascalCase" references/ram-policies.md; then
echo " ❌ 使用了 PascalCase 但未标注"
errors=$((errors + 1))
else
echo " ✅ 插件模式格式正确"
fi
if grep -q "describe-dts-jobs" references/ram-policies.md; then
echo " ✅ 使用了 plugin mode (describe-dts-jobs)"
else
echo " ⚠️ 未找到 plugin mode 格式 (但可能在其他位置)"
fi
# 检查 3: Description 触发语境
echo ""
echo "3. 检查 Description 触发语境..."
if grep -q "Use this skill when:" SKILL.md; then
echo " ✅ 有 'Use this skill when:' 触发语境"
else
echo " ❌ 缺少触发语境"
errors=$((errors + 1))
fi
echo ""
if [ $errors -eq 0 ]; then
echo "=== ✅ 所有检查通过 ==="
exit 0
else
echo "=== ❌ 有 $errors 项未通过 ==="
exit 1
fi
Related skills
FAQ
How many regions does it query?
It automatically queries all 27 public cloud regions if no region is specified, across 3 job types.
Is the task count reliable?
Yes. API retry logic with exponential backoff eliminates count variations, returning the same count consistently.