logo
0
0
WeChat Login
feat: 重构 CLI 命令行参数解析与集群配置管理

cnb-custom-env

一、项目依赖

1. go-cnb sdk

cnb提供了一些api的sdk,有go、python类型的,这里使用cnb/sdk/go-cnb

go get cnb.cool/cnb/sdk/go-cnb # 获取 go-cnb 的最新 tag 代码 go get cnb.cool/cnb/sdk/go-cnb@v1.0.0 # 获取 go-cnb 的特定 tag 代码 go mod tidy

2. 怎么使用?

import "cnb.cool/cnb/sdk/go-cnb/cnb"

创建一个 CNB Client, 然后使用一系列的服务来访问 CNB 的 API。

client, _ = cnb.NewClient(nil).WithAuthToken("...your cnb token...").WithURLs("...cnb base url...") repo, rsp, err := client.Repositories.GetRepo(ctx, repoName)

对于需要鉴权的 URL, 可以在 CNB 的 个人设置 -> 访问令牌中申请合适权限的 TOKEN。BaseURL 的规则为 api. 前缀加主域名,比如 https://api.cnb.cool/

二、一个简单示例

1. 源码

1.1 目录结构

➜ /workspace git:(main) ✗ tree . ├── Makefile ├── go.mod ├── go.sum ├── icnb │ └── client.go └── main.go

1.2 icnb/client.go

package icnb import ( "os" "cnb.cool/cnb/sdk/go-cnb/cnb" ) var Client *cnb.Client func init() { var err error token := os.Getenv("CNB_TOKEN") if token == "" { token = "xxxxxxx" } baseUrl := os.Getenv("CNB_BASE_URL") if baseUrl == "" { baseUrl = "https://api.cnb.cool/" } Client, err = cnb.NewClient(nil).WithAuthToken(token).WithURLs(baseUrl) if err != nil { panic(err) } }

1.3 main.go

package main import ( "context" "fmt" "log" "os" "cnb-custom-env/icnb" "cnb.cool/cnb/sdk/go-cnb/cnb" ) func main() { // 从命令行参数获取模式 if len(os.Args) < 2 { fmt.Println("用法: cce <mode> [args...]") fmt.Println("模式:") fmt.Println(" default <repo-slug> [branch] - 启动默认工作空间") fmt.Println(" custom - 启动自定义环境(固定参数)") fmt.Println("示例:") fmt.Println(" cce default sumu.k/cnb-custom-env main") fmt.Println(" cce custom") os.Exit(1) } mode := os.Args[1] switch mode { case "default": // 启动默认工作空间 if len(os.Args) < 3 { fmt.Println("用法: cce default <repo-slug> [branch]") fmt.Println("示例: cce default sumu.k/cnb-custom-env main") os.Exit(1) } repoSlug := os.Args[2] branch := "main" if len(os.Args) >= 4 { branch = os.Args[3] } if err := StartDefaultWorkspace(repoSlug, branch); err != nil { log.Fatalf("启动开发环境失败: %v", err) } case "custom": // 启动自定义环境(测试) if err := StartCustomEnvironment(); err != nil { log.Fatalf("启动自定义环境失败: %v", err) } default: fmt.Printf("未知模式: %s\n", mode) fmt.Println("可用模式: default, custom") os.Exit(1) } } /** * @brief 启动默认云原生开发环境 * * 镜像和配置来源:CNB 服务端会读取目标仓库指定分支下的 .cnb.yml 配置文件 * 例如:repoSlug="sumu.k/cnb-custom-env", branch="main" 时,读取该仓库 main 分支的 .cnb.yml * .cnb.yml 中定义了开发环境镜像 (docker.image)、服务 (services)、启动脚本 (stages) 等配置 * * @param repoSlug 仓库标识,格式为 "用户名/仓库名",如 "sumu.k/cnb-custom-env" * @param branch 分支名称,默认使用 "main" * @return 成功返回 nil,失败返回 error */ func StartDefaultWorkspace(repoSlug, branch string) error { log.Printf("🚀 正在启动开发环境: %s (分支: %s)", repoSlug, branch) rst, rsp, err := icnb.Client.Workspace.StartWorkspace(context.TODO(), repoSlug, &cnb.StartWorkspaceRequest{ Branch: branch, Ref: fmt.Sprintf("refs/heads/%s", branch), }) if err != nil { log.Printf("❌ 启动失败: %v", err) return err } if rsp.StatusCode != 200 { log.Printf("❌ 启动失败, 状态码: %d", rsp.StatusCode) return fmt.Errorf("启动失败, 状态码: %d", rsp.StatusCode) } log.Printf("🎉 开发环境启动成功!") log.Printf("📡 访问地址: %s", rst.Url) log.Printf("📋 构建日志: %s", rst.BuildLogUrl) log.Printf("🔢 工作空间 SN: %s", rst.Sn) if rst.Message != "" { log.Printf("💬 消息: %s", rst.Message) } return nil } /** * @brief 生成配置 YAML * * 根据镜像、CPU 核数和集群标签生成构建配置 YAML * * @param image 镜像地址 * @param cpus CPU 核数 * @param tag 集群标签 * @return 配置 YAML 字符串 */ func generateConfigYAML(image string, cpus int, tag string) string { return fmt.Sprintf(`.vscode: &vscode api_trigger_sumu: clouddev: docker: image: %s runner: cpus: %d tags: - %s services: - vscode - docker pipeline: runner: cpus: %d tags: - %s include: - config: $: *vscode - path: .cnb.yml ignoreError: true`, image, cpus, tag, cpus, tag) } /** * @brief 启动自定义环境(简化版) * * 使用固定参数启动自定义构建环境,镜像和集群配置预定义 * * @return 成功返回 nil,失败返回 error */ func StartCustomEnvironment() error { // 固定参数配置 repoSlug := "W3C/sumu/cnb-demo" branch := "main" image := "docker.cnb.cool/sumu.k/docker-learning/embedded-env" cpus := 8 tag := "cnb:arch:amd64" log.Printf("🚀 Preparing to start custom environment for %s on branch %s", repoSlug, branch) // 显示配置摘要 log.Printf("📊 Environment configuration:") log.Printf(" Repository: %s", repoSlug) log.Printf(" Branch: %s", branch) log.Printf(" Image: %s", image) log.Printf(" Cluster: %s (AMD64架构通用集群)", tag) log.Printf(" Architecture: amd64") log.Printf(" CPU cores: %d", cpus) // 生成配置 YAML configYaml := generateConfigYAML(image, cpus, tag) log.Printf("⏳ Starting build process...") rst, rsp, err := icnb.Client.Build.StartBuild(context.TODO(), repoSlug, &cnb.StartBuildRequest{ Branch: branch, Config: configYaml, Env: map[string]string{}, Event: "api_trigger_sumu", Sha: "", Sync: "", Tag: "", }) if err != nil { log.Printf("❌ Error starting custom environment: %v", err) return err } if rsp.StatusCode != 200 { log.Printf("❌ Failed to start custom environment. Status: %d", rsp.StatusCode) return fmt.Errorf("failed to start custom environment, status code: %d", rsp.StatusCode) } log.Printf("🎉 Successfully started custom environment!") log.Printf("📝 Build log URL: %v", rst.BuildLogUrl) log.Printf("📊 Final resource allocation: %d CPUs on %s cluster", cpus, tag) // 提供使用提示 log.Printf("💡 Usage tips:") log.Printf(" • You're using AMD64 architecture - suitable for most development scenarios") log.Printf(" • CPU range: 1-64 cores (default: 8)") log.Printf(" • Environment initialization may take a few minutes") log.Printf(" • Check the build logs for detailed progress information") return nil }

1.4 Makefile

# 项目名称 TARGET := cce # 成果物目录 BIN_DIR := bin # 成果物路径 BINARY := $(BIN_DIR)/$(TARGET) # 源码文件(自动匹配) SRC_FILES := $(wildcard *.go **/*.go) # 编译(使用隐含规则,自动判断是否需要重新编译) $(BINARY): $(SRC_FILES) @mkdir -p $(BIN_DIR) go build -o $@ . # 运行 run: $(BINARY) ./$(BINARY) W3C/sumu/cnb-demo # 测试默认工作空间 env_default: $(BINARY) ./$(BINARY) default W3C/sumu/cnb-demo # 测试自定义环境 env_custom: $(BINARY) ./$(BINARY) custom # 清理 clean: rm -rf $(BIN_DIR) .PHONY: run env_default env_custom clean

1.5 go.mod

module cnb-custom-env go 1.26.1 require cnb.cool/cnb/sdk/go-cnb v1.18.8 require github.com/google/go-querystring v1.1.0 // indirect

2. 同步依赖

参考:管理依赖 - Go 编程语言 - Go 编程语言

安装模块后会自动更新这个文件,我们还需要同步代码依赖项:

go mod tidy

3. 编译测试

make # 编译 make env_default # 使用指定仓库的.cnb.yml启动默认云原生开发环境 make env_custom # 使用自定义参数(测试程序内部固定了)启动云原生开发环境

参考项目:znb/start-custom-environment

参考资料:

能否通过API创建一个云原生开发环境 · Issue #1000 · cnb/feedback