package setting import ( "code.gitea.io/gitea/modules/log" ) const ( KUBERNETES = "kubernetes" // 支持 "k8s" 和 "kubernetes" DOCKER = "docker" ) // 检查用户输入的 DevContainer Agent 是否有效 func isValidAgent(agent string) bool { return agent == "k8s" || agent == KUBERNETES || agent == DOCKER } const ( CLOUD_PROVIDER_TENCENT = "tencent" DEVCONTAINER_CLOUD_NAT_RULE_DESCRIPTION_PREFIX = "DevContainer: " ) // validCloudProviderSet 私有 Set 结构,标识目前系统所有支持的 Cloud Provider 类型 var validCloudProviderSet = map[string]struct{}{ CLOUD_PROVIDER_TENCENT: {}, } type DevcontainerType struct { Enabled bool Host string Agent string Namespace string TimeoutSeconds int64 DefaultGitBranchName string DefaultDevcontainerImageName string DockerHost string } type SSHKeyPairType struct { KeySize int } type CloudType struct { Enabled bool Provider string Tencent CloudProviderTencentType // 移除 ini 标签,通过代码处理 } type CloudProviderTencentType struct { Endpoint string Region string NatGatewayId string PublicIpAddress string PrivateIpAddress string IpProtocol string SecretId string SecretKey string } var Devcontainer = DevcontainerType{ Enabled: false, Namespace: "default", TimeoutSeconds: 900, // Max wait time for DevContainer to be ready (blocking), default is 15 minutes, can be overridden by app.ini DefaultGitBranchName: "main", // Default branch name for .devcontainer/devcontainer.json DefaultDevcontainerImageName: "devstar.cn/public/base-ssh-devcontainer:ubuntu-20.04-20241014", // Default image if not specified } var SSHKeypair = SSHKeyPairType{ KeySize: 2048, // Size of the SSH key } var Cloud = CloudType{ Enabled: false, // Cloud feature toggle } // validateDevcontainerSettings 检查从 ini 配置文件中读取 DevStar DevContainer 配置信息,若数据无效,则自动禁用 DevContainer func validateDevcontainerSettings() { // 检查 Host 是否为空,若为空,则自动将 DevContainer 设置为禁用 if len(Devcontainer.Host) == 0 { log.Warn("INVALID config 'host' for DevStar DevContainer") Devcontainer.Enabled = false } // 检查用户输入的 DevContainer Agent 是否存在支持列表,若不支持,则将 DevContainer 设置为禁用 if !isValidAgent(Devcontainer.Agent) { log.Warn("Invalid config 'agent' for DevStar DevContainer") Devcontainer.Enabled = false } // 检查默认分支名称设置 if len(Devcontainer.DefaultGitBranchName) == 0 { log.Warn("INVALID config 'DefaultGitBranchName' for DevStar DevContainer") Devcontainer.Enabled = false } // 检查默认 DevContainer Image if len(Devcontainer.DefaultDevcontainerImageName) == 0 { log.Warn("INVALID config 'DefaultGitBranchNameDefaultDevcontainerImageName' for DevStar DevContainer") Devcontainer.Enabled = false } if Devcontainer.Enabled == false { log.Warn("DevStar DevContainer Service Disabled") } else { log.Info("DevStar DevContainer Service Enabled") } } // validateSSHKeyPairSettings 检查从 ini 配置文件中读取 DevStar SSH Key Pair 配置信息 func validateSSHKeyPairSettings() { if SSHKeypair.KeySize < 1024 { SSHKeypair.KeySize = 1024 } } // validateDevcontainerCloudSettings 检查从 ini 配置文件中读取 DevStar Cloud 配置信息 func validateDevcontainerCloudSettings() { switch Cloud.Provider { case CLOUD_PROVIDER_TENCENT: // 腾讯云配置检查 if len(Cloud.Tencent.NatGatewayId) < 4 { log.Warn("INVALID NAT Gateway ID '%v' for DevStar Cloud Provider Tencent", Cloud.Tencent.NatGatewayId) Cloud.Enabled = false } if Cloud.Tencent.IpProtocol != "TCP" && Cloud.Tencent.IpProtocol != "UDP" && Cloud.Tencent.IpProtocol != "tcp" && Cloud.Tencent.IpProtocol != "udp" { log.Warn("INVALID IP Protocol '%v' for DevStar Cloud Provider Tencent", Cloud.Tencent.IpProtocol) Cloud.Enabled = false } if len(Cloud.Tencent.Region) < 3 || len(Cloud.Tencent.Endpoint) == 0 { log.Warn("INVALID (Region, Endpoint) pair ('%v', '%v') for DevStar Cloud Provider Tencent", Cloud.Tencent.Region, Cloud.Tencent.Endpoint) Cloud.Enabled = false } if len(Cloud.Tencent.PrivateIpAddress) == 0 || len(Cloud.Tencent.PublicIpAddress) == 0 { log.Warn("INVALID (PublicIpAddress, PrivateIpAddress) pair ('%v', '%v') for DevStar Cloud Provider Tencent", Cloud.Tencent.PublicIpAddress, Cloud.Tencent.PrivateIpAddress) Cloud.Enabled = false } if len(Cloud.Tencent.SecretId) == 0 || len(Cloud.Tencent.SecretKey) == 0 { log.Warn("INVALID (SecretId, SecretKey) pair for DevStar Cloud Provider Tencent") Cloud.Enabled = false } default: // 无效 Cloud Provider 名称 log.Warn("INVALID config '%v' for DevStar Cloud", Cloud.Provider) Cloud.Enabled = false } if Cloud.Enabled == false { log.Warn("DevStar Cloud Provider Service Disabled") } else { log.Info("DevStar Cloud Provider '%v' Enabled", Cloud.Provider) } } // 修改 loadDevcontainerFrom 函数以支持新旧配置节 func loadDevcontainerFrom(rootCfg ConfigProvider) { // 检查是否存在新的配置节 hasNewConfig := true if _, err := rootCfg.GetSection("devcontainer"); err != nil { hasNewConfig = false } // 检查是否存在旧的配置节 hasOldConfig := true if _, err := rootCfg.GetSection("devstar.devcontainer"); err != nil { hasOldConfig = false } // 根据存在的配置节处理 if hasNewConfig { // 新配置节存在,直接使用 mustMapSetting(rootCfg, "devcontainer", &Devcontainer) log.Info("从 [devcontainer] 节加载配置") } else if hasOldConfig { // 只有旧配置节存在,直接从旧配置节加载 mustMapSetting(rootCfg, "devstar.devcontainer", &Devcontainer) log.Info("从 [devstar.devcontainer] 节加载配置") } // 进行配置验证 validateDevcontainerSettings() // 加载其他配置 mustMapSetting(rootCfg, "ssh_key_pair", &SSHKeypair) validateSSHKeyPairSettings() if Devcontainer.Agent == "k8s" || Devcontainer.Agent == KUBERNETES { // 调用新的云配置加载函数 loadCloudConfigWithFallback(rootCfg) } // 打印最终使用的命名空间 log.Info("DevContainer 将在命名空间 '%s' 中创建", Devcontainer.Namespace) } // 新增: 处理云配置加载的函数,支持新旧两种配置节 func loadCloudConfigWithFallback(rootCfg ConfigProvider) { // 1. 先尝试加载主配置节 hasDevcontainerCloud := true if _, err := rootCfg.GetSection("devcontainer.cloud"); err != nil { hasDevcontainerCloud = false } hasDevstarCloud := true if _, err := rootCfg.GetSection("devstar.cloud"); err != nil { hasDevstarCloud = false } // 2. 优先使用新配置节,不存在则使用旧配置节 var cloudSectionName string if hasDevcontainerCloud { cloudSectionName = "devcontainer.cloud" log.Info("从 [devcontainer.cloud] 节加载云配置") } else if hasDevstarCloud { cloudSectionName = "devstar.cloud" log.Info("从 [devstar.cloud] 节加载云配置") } else { log.Warn("未找到云配置节,Cloud 功能将被禁用") Cloud.Enabled = false return } // 3. 加载基本云配置 if err := rootCfg.Section(cloudSectionName).MapTo(&Cloud); err != nil { log.Error("加载云配置时出错: %v", err) Cloud.Enabled = false return } // 4. 根据选择的配置节路径,决定腾讯云配置节路径 var tencentSectionName string if cloudSectionName == "devcontainer.cloud" { tencentSectionName = "devcontainer.cloud.tencent" } else { tencentSectionName = "devstar.cloud.tencent" } // 5. 检查腾讯云配置节是否存在 if _, err := rootCfg.GetSection(tencentSectionName); err != nil { log.Warn("未找到腾讯云配置节 [%s]", tencentSectionName) if Cloud.Provider == CLOUD_PROVIDER_TENCENT { log.Error("虽然指定使用腾讯云,但未找到对应配置,Cloud 功能将被禁用") Cloud.Enabled = false } return } // 6. 加载腾讯云配置 if Cloud.Provider == CLOUD_PROVIDER_TENCENT { log.Info("从 [%s] 节加载腾讯云配置", tencentSectionName) if err := rootCfg.Section(tencentSectionName).MapTo(&Cloud.Tencent); err != nil { log.Error("加载腾讯云配置时出错: %v", err) Cloud.Enabled = false return } } // 7. 验证云配置 validateDevcontainerCloudSettings() }