Back to skills
extension
Category: OtherAPI key required

腾讯云 COS 迁移助手

自动化腾讯云对象存储(COS)迁移助手,支持从阿里云OSS等第三方云存储迁移到腾讯云COS。 通过自然对话收集凭证、浏览资源、创建迁移任务、监控进度。当用户需要进行云存储迁移、 数据迁移、OSS迁移、COS迁移、跨云迁移、存储桶数据迁移时使用此技能。

personAuthor: user_7f95d0c2hubcommunity

自动化腾讯云 COS 迁移助手

通过自然语言对话,将阿里云 OSS 对象存储数据迁移到腾讯云 COS。

🎯 核心特性

  • 💬 对话式交互: 通过自然对话收集凭证、选择资源
  • 📂 资源浏览: 自动列出OSS和COS存储桶供选择
  • 🤖 自动化迁移: 一键创建MSP迁移任务
  • 📊 任务管理: 查看任务状态和基本进度信息
  • 🛡️ 基础安全: 凭证脱敏显示,日志记录保护
  • 📋 迁移报告: 任务完成后生成基本统计报告

🚀 触发关键词

当用户提到以下关键词时触发此技能:

  • "迁移 OSS 到 COS"
  • "阿里云迁移到腾讯云"
  • "云存储迁移"
  • "COS 迁移"
  • "OSS 迁移"
  • "跨云迁移"

💡 支持的功能

1. 配置凭证

配置阿里云 OSS 和腾讯云 COS 的访问凭证。

表达方式:

  • "配置凭证"
  • "设置密钥"
  • "configure credentials"

2. 查看存储桶

列出阿里云 OSS 或腾讯云 COS 的存储桶。

表达方式:

  • "查看我的桶"
  • "列出存储桶"
  • "查看 OSS 桶"
  • "显示 COS 桶"

3. 查看文件列表

查看指定存储桶内的文件列表。

表达方式:

  • "查看 xxhu-oss-hdfs 桶的文件"
  • "查看 OSS 桶 my-bucket 里有什么文件"
  • "列出 bucket-123 的文件"
  • "看看 my-bucket 里面有什么"
  • "桶里有什么文件"

注意: 需要先配置凭证,支持指定 OSS 或 COS provider。


4. 查看迁移参数

查看所有迁移任务参数及其默认值。

表达方式:

  • "查看迁移参数"
  • "有哪些参数"
  • "显示所有参数"
  • "迁移参数列表"
  • "所有参数"
  • "当前配置"

5. 创建迁移任务

创建单个迁移任务,从源桶迁移到目标桶。

表达方式:

  • "从 bucket-a 迁移到 bucket-b"
  • "开始迁移"
  • "创建迁移任务"
  • "数据迁移"
  • "传输数据"

6. 批量创建迁移任务

从 Excel 文件批量创建多个迁移任务。

表达方式:

  • "批量创建迁移任务"
  • "从文件创建任务"
  • "上传 Excel 创建任务"
  • "批量迁移"

文件格式要求:

  • 第1行:参数名称
  • 第2行:参数说明
  • 第3行开始:迁移任务数据
  • 必需参数:JobName, SrcBucket, DstBucket

7. 查看任务状态

查看迁移任务的执行状态和进度。

表达方式:

  • "查看任务状态"
  • "任务进度如何"
  • "查看迁移任务"
  • "监控任务"
  • "任务情况"

💬 对话式工作流程

场景 1: 首次使用(无凭证)

AI: 检测到你还没有配置云存储凭证。请提供:

    📦 阿里云 OSS(源端):
    1. AccessKey ID
    2. AccessKey Secret
    3. 区域(如 oss-cn-hangzhou)

用户: 我的 AccessKey ID 是 LTAI4***, Secret 是 abc***, 区域是 oss-cn-hangzhou

AI: ✅ 阿里云凭证已验证。请提供腾讯云凭证:

    📦 腾讯云 COS(目标端):
    1. Secret ID
    2. Secret Key
    3. 区域(如 ap-guangzhou)

用户: 我的 Secret ID 是 AKID***, Secret Key 是 ***

AI: ✅ 凭证已安全保存。正在列出你的存储桶...

    📦 阿里云 OSS 存储桶:
    1. my-images
    2. my-logs
    3. my-backup

    请选择要迁移的源桶?

用户: 我想迁移 my-images

AI: 📦 腾讯云 COS 存储桶:
    1. backup-bucket-1234567890
    2. images-bucket-1234567890

    请选择目标桶?

用户: 用 images-bucket-1234567890

AI: 📋 迁移配置确认:

    源端: my-images
    目标: images-bucket-1234567890
    覆盖模式: 跳过同名文件

    确认开始迁移? (是/否)

用户: 是

AI: 🚀 迁移任务已创建!
    任务 ID: task-abc1234567890

    使用以下命令查看任务状态:
    cos-migrate status --task-id task-abc1234567890

场景 2: 已有凭证

用户: 帮我迁移 OSS 到 COS

AI: ✅ 检测到已保存的凭证。正在列出存储桶...

    📦 阿里云 OSS 存储桶:
    ...

    [继续选择流程]

场景 3: 查询任务进度

用户: 查看我的迁移任务进度

AI: 📋 迁移任务列表:

    1. ✅ migration-20260330 (已完成)
       源: my-images → 目标: images-bucket

    2. 🔄 migration-20260331 (运行中)
       源: my-logs → 目标: logs-bucket

    输入任务 ID 查看详细信息

⚠️ 操作确认

以下操作需要二次确认:

| 操作 | 确认方式 | |------|----------| | 取消迁移任务 | 使用 --confirm 参数或确认提示

确认话术示例:

⚠️ **操作确认**

你即将执行: 取消迁移任务
任务 ID: task-abc1234567890

此操作将:
- 停止正在进行的迁移任务
- 已迁移的文件不会回滚

请添加 --confirm 参数来确认执行,或取消操作

🔒 安全机制

敏感信息处理

| 场景 | 处理方式 | |------|----------| | 用户输入 Secret | 脱敏显示,避免完整暴露 | | 显示已保存凭证 | 脱敏显示: LTAI4***7890 | | 日志安全 | 敏感信息记录时进行遮蔽处理 |

凭证存储

  • 存储方式: 本地文件存储(建议用户自行确保文件安全)
  • 日志文件: ~/.cos-migration/logs/migration-YYYY-MM-DD.log

📦 迁移模式

| 模式 | 说明 | 状态 | |------|------|------| | 全托管迁移 | MSP 通过公网从阿里云OSS拉取数据到腾讯云COS | ✅ 支持 | | 半托管迁移 | 在源端部署Agent推送数据(当前硬编码配置) | ⚠️ 实验性 |

注意: 当前版本主要支持全托管迁移模式。半托管模式需要额外的Agent部署配置。

🛠️ CLI 工具(可选)

除了对话式交互,也可以使用 CLI 工具:

# 安装依赖
cd {baseDir}
npm install

# 配置凭证
npm run dev config -- --show

# 列出存储桶
npm run dev list-buckets -- --oss
npm run dev list-buckets -- --cos

# 创建迁移任务
npm run dev migrate -- --source my-oss-bucket --target my-cos-bucket

# 查看任务状态
npm run dev status -- --task-id task-xxx

# 查看所有任务
npm run dev tasks

🛠️ 本工程客户端使用示例

本工程封装了 OSS、COS 和 MSP 客户端,提供统一的 API 接口。以下是各客户端的使用方法。

OSS 客户端(阿里云)

import { OSSClient } from './lib/oss-client';

/**
 * 初始化 OSS 客户端
 */
const ossClient = new OSSClient(
  accessKeyId,      // 阿里云 AccessKeyID
  accessKeySecret,  // 阿里云 AccessKeySecret
  region            // 区域,如 'oss-cn-hangzhou'
  // bucket           // 可选:指定默认桶
);

/**
 * 列出所有存储桶
 */
const buckets = await ossClient.listBuckets();
// 返回: BucketInfo[] { name, location, creationDate, storageClass }

/**
 * 列出桶内文件
 */
const files = await ossClient.listFiles(bucketName, prefix);
// 返回: FileInfo[] { key, size, lastModified, etag, storageClass }

/**
 * 获取桶统计信息
 */
const stats = await ossClient.getBucketStats(bucketName, prefix);
// 返回: BucketStats { fileCount, totalSize, lastModified }

/**
 * 验证凭证是否有效
 */
const isValid = await ossClient.validateCredentials();

/**
 * 获取文件签名 URL(用于直接下载)
 */
const url = await ossClient.getSignedUrl(bucketName, objectKey, expires);

COS 客户端(腾讯云)

import { COSClient } from './lib/cos-client';

/**
 * 初始化 COS 客户端
 */
const cosClient = new COSClient(
  secretId,   // 腾讯云 SecretId
  secretKey,  // 腾讯云 SecretKey
  region      // 区域,如 'ap-guangzhou'
);

/**
 * 列出所有存储桶
 */
const buckets = await cosClient.listBuckets();
// 返回: BucketInfo[] { name, location, creationDate, storageClass }

/**
 * 列出桶内文件
 */
const files = await cosClient.listFiles(bucketName, prefix);
// 返回: FileInfo[] { key, size, lastModified, etag, storageClass }

/**
 * 检查存储桶是否存在
 */
const exists = await cosClient.bucketExists(bucketName);

/**
 * 获取桶统计信息
 */
const stats = await cosClient.getBucketStats(bucketName, prefix);
// 返回: BucketStats { fileCount, totalSize, lastModified }

/**
 * 检查文件是否存在
 */
const fileExists = await cosClient.fileExists(bucketName, key);

/**
 * 验证凭证是否有效
 */
const isValid = await cosClient.validateCredentials();

/**
 * 删除文件(高危操作)
 */
await cosClient.deleteFile(bucketName, key);

/**
 * 批量删除文件(高危操作)
 */
await cosClient.deleteFiles(bucketName, [key1, key2, ...]);

MSP 客户端(腾讯云迁移服务)

import { MSPClient } from './lib/msp-client';

/**
 * 初始化 MSP 客户端
 */
const mspClient = new MSPClient({
  secretId,   // 腾讯云 SecretId
  secretKey,  // 腾讯云 SecretKey
  region      // 可选,默认调用 MSP API
});

/**
 * 创建迁移任务
 */
const result = await mspClient.createMigrationTask({
  JobName: 'migration-task-001',
  SrcBucket: 'source-bucket',
  DstBucket: 'target-bucket-1250000000',
  SrcSecretId: aliyunAccessKeyId,
  SrcSecretKey: aliyunAccessKeySecret,
  DstSecretId: tencentSecretId,
  DstSecretKey: tencentSecretKey,
  // 可选参数
  SrcService: 'OSS',           // 默认 'OSS'
  DstService: 'COS',           // 默认 'COS'
  FileOverWrite: 1,            // 0=覆盖, 1=跳过,默认 1
  StorageType: 3,              // 存储类型,默认 3(保持原属性)
  Mode: 0,                     // 0=全托管, 1=半托管,默认 0
  HasFileTime: 0,              // 是否时间过滤,默认 0
  StartTime: '2025-01-01 00:00:00',  // HasFileTime=1 时必需
  EndTime: '2025-12-31 23:59:59'     // HasFileTime=1 时必需
});
// 返回: { JobId: string, RequestId: string }

/**
 * 查询任务列表
 */
const tasks = await mspClient.listTasks({
  JobId: 'fm-xxx',  // 可选:指定任务 ID
  Offset: 0,        // 可选:偏移量
  Limit: 100        // 可选:限制数量
});
// 返回: MSPJobInfo[] { JobId, JobName, Status, StatusId, Progress, ... }

/**
 * 查询任务详情
 */
const taskDetail = await mspClient.getTaskDetail(jobId);
// 返回: MSPJobInfo

/**
 * 获取任务状态
 */
const status = await mspClient.getTaskStatus(jobId);
// 返回: { taskId, status, totalFiles, completedFiles, failedFiles, ... }

/**
 * 获取迁移结果
 */
const result = await mspClient.getMigrationResult(jobId);
// 返回: { taskId, status, totalFiles, successFiles, failedFiles, ... }

/**
 * 取消任务
 */
await mspClient.cancelTask(jobId);

/**
 * 验证凭证是否有效
 */
const isValid = await mspClient.validateCredentials();

任务状态码对照

本工程的 MSPClient 使用以下状态映射:

| StatusId | 状态文本 | 本工程状态 | |----------|----------|-----------| | 1 | 等待中 | pending | | 2 | 扫描中 | running | | 3 | 迁移中 | running | | 4 | 校验中 | running | | 5 | 完成 | completed | | 6 | 失败 | failed | | 7 | 取消 | cancelled | | 8 | 等待中 | pending | | 9 | 任务完成 | completed |

参数依赖关系

某些参数之间存在依赖关系,配置时需要注意:

| 参数 | 依赖条件 | 说明 | |------|----------|------| | SavePath | SaveType=1 | 只有保存到指定目录时才需要 | | FileStartTime / FileEndTime | HasFileTime=1 | 启用时间过滤时需要 | | ListerIp / EndPoint | Mode=1 | 半托管模式必需 |

创建任务完整参数示例

以下是使用 MSPClient.createMigrationTask() 创建迁移任务的完整参数说明:

最小配置示例

await mspClient.createMigrationTask({
  JobName: 'my-migration-task',
  SrcBucket: 'my-source-bucket',
  DstBucket: 'my-target-bucket-1250000000',
  SrcSecretId: 'LTAI5txxxx',
  SrcSecretKey: 'xxxxx',
  DstSecretId: 'AKIDxxxxx',
  DstSecretKey: 'xxxxx'
});

完整参数示例

await mspClient.createMigrationTask({
  // ===== 基本信息 =====
  JobName: 'aliyun-to-cos-migration-20250413',

  // ===== 源端配置 =====
  SrcBucket: 'my-source-bucket',
  SrcSecretId: process.env.ALIYUN_OSS_ACCESS_KEY_ID,
  SrcSecretKey: process.env.ALIYUN_OSS_ACCESS_KEY_SECRET,
  SrcService: 'OSS',  // 可选,默认 'OSS'

  // ===== 目标端配置 =====
  DstBucket: 'my-target-bucket-1250000000',
  DstSecretId: process.env.TENCENT_COS_SECRET_ID,
  DstSecretKey: process.env.TENCENT_COS_SECRET_KEY,
  DstService: 'COS',  // 可选,默认 'COS'

  // ===== Header 迁移设置 =====
  MigrationHeaderType: 1,  // 1=保留全部,2=丢弃全部,3=自定义替换,默认 1
  MigrationHeader: [  // MigrationHeaderType=3 时需要
    { origin: 'x-oss-meta-a', cos: 'x-cos-meta-a' }
  ],

  // ===== 文件过滤规则 =====
  MigrationRuleType: 1,  // 1=不过滤,2=前缀匹配,3=正则匹配,默认 1
  MigrationRule: ['images/', 'videos/'],  // MigrationRuleType=2/3 时需要

  // ===== 时间过滤 =====
  HasFileTime: 1,  // 0=不启用,1=启用,默认 0
  StartTime: '2025-01-01 00:00:00',  // HasFileTime=1 时必需
  EndTime: '2025-12-31 23:59:59',    // HasFileTime=1 时必需

  // ===== 文件冲突处理 =====
  FileOverWrite: 1,  // 0=覆盖同名文件,1=跳过同名文件,默认 1

  // ===== 目标存储类型 =====
  StorageType: 3,  // 1=标准,2=低频,3=保持原属性,4=归档,5=智能分层,6=冷存储,默认 3

  // ===== Agent 模式 =====
  Mode: 0,  // 0=全托管,1=半托管,默认 0

  // ===== 半托管模式参数(Mode=1 时必需)=====
  ListerIp: 'xx.xx.xx.xx',  // Agent 服务器 IP
  EndPoint: 'oss-cn-beijing-internal.aliyuncs.com',  // 源端 Endpoint

  // ===== 限速设置 =====
  IsLimitSpeed: 0,  // 0=不限速,1=限速,默认 0
  LimitSpeed: 100,  // 限速值(KB/s),IsLimitSpeed=1 时需要
  LimitQPS: 1000,   // QPS 限制

  // ===== 预估信息 =====
  EstimateDataSize: 1000,    // 预估数据大小(GB)
  EstimateFileCount: 100000, // 预估文件数量

  // ===== 保存路径 =====
  SaveType: 0,  // 0=保存到根目录,1=保存到指定目录,默认 0
  // SavePath: '/migrated/',  // SaveType=1 时需要

  // ===== 定时迁移 =====
  IsCron: 0  // 0=否,1=是,默认 0
});

参数说明对照表

| 参数 | 类型 | 必填 | 默认值 | 说明 | |------|------|------|--------|------| | 基本信息 | | JobName | string | ✅ | - | 任务名称,建议格式:{用途}-{日期} | | 源端配置 | | SrcBucket | string | ✅ | - | 源存储桶名称 | | SrcSecretId | string | ✅ | - | 源端 SecretId/AccessKeyID | | SrcSecretKey | string | ✅ | - | 源端 SecretKey/AccessKeySecret | | SrcService | string | ❌ | OSS | 源服务类型:OSS/COS/AWS/Qiniu | | 目标端配置 | | DstBucket | string | ✅ | - | 目标存储桶名称(需包含 APPID) | | DstSecretId | string | ✅ | - | 目标端 SecretId | | DstSecretKey | string | ✅ | - | 目标端 SecretKey | | DstService | string | ❌ | COS | 目标服务类型:COS | | Header 迁移 | | MigrationHeaderType | int | ❌ | 1 | 1=保留全部,2=丢弃全部,3=自定义替换 | | MigrationHeader | array | ❌ | [] | Header 替换规则,MigrationHeaderType=3 时需要 | | 文件过滤 | | MigrationRuleType | int | ❌ | 1 | 1=不过滤,2=前缀匹配,3=正则匹配 | | MigrationRule | array | ❌ | [] | 过滤规则,MigrationRuleType=2/3 时需要 | | 时间过滤 | | HasFileTime | int | ❌ | 0 | 0=不启用,1=启用时间过滤 | | StartTime | string | 条件 | - | 开始时间,HasFileTime=1 时必需,格式:yyyy-MM-dd HH:mm:ss | | EndTime | string | 条件 | - | 结束时间,HasFileTime=1 时必需,格式:yyyy-MM-dd HH:mm:ss | | 文件冲突 | | FileOverWrite | int | ❌ | 1 | 0=覆盖同名文件,1=跳过同名文件 | | 存储类型 | | StorageType | int | ❌ | 3 | 1=标准,2=低频,3=保持原属性,4=归档,5=智能分层,6=冷存储 | | Agent 模式 | | Mode | int | ❌ | 0 | 0=全托管,1=半托管 | | ListerIp | string | 条件 | - | Agent IP,Mode=1 时必需 | | EndPoint | string | 条件 | - | 源端 Endpoint,Mode=1 时必需 | | 限速 | | IsLimitSpeed | int | ❌ | 0 | 0=不限速,1=限速 | | LimitSpeed | int | ❌ | 0 | 限速值(KB/s),IsLimitSpeed=1 时需要 | | LimitQPS | int | ❌ | 0 | QPS 限制 | | 预估信息 | | EstimateDataSize | int | ❌ | 0 | 预估数据大小(GB) | | EstimateFileCount | int | ❌ | 0 | 预估文件数量 | | 保存路径 | | SaveType | int | ❌ | 0 | 0=根目录,1=指定目录 | | SavePath | string | 条件 | - | 保存路径,SaveType=1 时需要 | | 定时迁移 | | IsCron | int | ❌ | 0 | 0=否,1=是定时任务 |

❓ 常见问题

Q1: 迁移过程中源端数据变更怎么办?

当前版本创建的是一次性全量迁移任务。如需同步增量数据,需要重新创建迁移任务。同名文件处理策略基于MSP服务的默认配置。

Q2: 迁移失败如何处理?

  1. 查看任务状态和失败文件列表
  2. 失败原因会记录在任务结果中
  3. 可根据失败原因手动处理源文件后重新创建迁移任务

Q3: 凭证存储安全吗?

  • 凭证以脱敏形式显示,避免完整暴露
  • 建议用户妥善保管本地存储的凭证文件
  • 日志中会避免记录完整的敏感信息

📚 参考文档