This commit is contained in:
kun.wang 2025-04-27 15:41:01 +08:00
commit af4582c591
32 changed files with 977 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

BIN
go/.DS_Store vendored Normal file

Binary file not shown.

3
go/go.mod Normal file
View File

@ -0,0 +1,3 @@
// go.mod
module gitlab.hobot.cc/dep/d-cloud/infra/deploy
go 1.23.4

280
go/main/main.go Normal file
View File

@ -0,0 +1,280 @@
// main.go
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"os/exec"
"path/filepath"
"strings"
"sync"
"time"
)
// BuildRequest represents a build job in the queue
type BuildRequest struct {
RepoURL string
Branch string
}
// BuildQueue manages the build requests
type BuildQueue struct {
queue []BuildRequest
mu sync.Mutex
}
var buildQueue = &BuildQueue{}
// Add adds a new build request to the queue
func (bq *BuildQueue) Add(req BuildRequest) {
bq.mu.Lock()
defer bq.mu.Unlock()
bq.queue = append(bq.queue, req)
go bq.processQueue() // Start processing if not already running
}
// processQueue handles the build requests one at a time
func (bq *BuildQueue) processQueue() {
bq.mu.Lock()
if len(bq.queue) == 0 {
bq.mu.Unlock()
return
}
// Get the next request
req := bq.queue[0]
queueLength := len(bq.queue) - 1 // 减去当前正在处理的请求
bq.queue = bq.queue[1:]
bq.mu.Unlock()
// 发送准备构建通知
webhookURL := "https://open.feishu.cn/open-apis/bot/v2/hook/8648822c-fbf8-45ba-bd4d-907c2abdb885"
if err := sendFeishuNotification(webhookURL, &req, "", "prepare", queueLength); err != nil {
log.Printf("发送准备构建通知失败: %v", err)
}
// Process the build request
err := processBuild(&req)
if err != nil {
log.Printf("Error processing build: %v", err)
}
// Process next item in queue
go bq.processQueue()
}
func processBuild(req *BuildRequest) error {
log.Printf("开始处理构建请求 - 仓库: %s, 分支: %s", req.RepoURL, req.Branch)
// 发送开始构建通知
webhookURL := "https://open.feishu.cn/open-apis/bot/v2/hook/8648822c-fbf8-45ba-bd4d-907c2abdb885"
if err := sendFeishuNotification(webhookURL, req, "", "start", 0); err != nil {
log.Printf("发送开始构建通知失败: %v", err)
}
// Create a temporary directory for the build
buildDir, err := os.MkdirTemp("", "build-*")
if err != nil {
return fmt.Errorf("创建构建目录失败: %v", err)
}
log.Printf("创建临时构建目录: %s", buildDir)
defer func() {
log.Printf("清理临时构建目录: %s", buildDir)
os.RemoveAll(buildDir)
}()
// Clone the repository
log.Printf("开始克隆仓库...")
cloneCmd := exec.Command("git", "clone", "-b", req.Branch, req.RepoURL, buildDir)
output, err := cloneCmd.CombinedOutput()
if err != nil {
return fmt.Errorf("git clone失败:\n命令输出: %s\n错误: %v", string(output), err)
}
log.Printf("仓库克隆成功")
// 获取版本号
log.Printf("获取版本号...")
cmd := exec.Command("git", "describe", "--tags", "--abbrev=0", "--exact-match", "HEAD")
cmd.Dir = buildDir
version, err := cmd.Output()
if err != nil {
// 如果没有tag则使用commit id
cmd = exec.Command("git", "rev-parse", "--short", "HEAD")
cmd.Dir = buildDir
version, err = cmd.Output()
if err != nil {
return fmt.Errorf("获取commit id失败: %v", err)
}
}
versionStr := strings.TrimSpace(string(version))
log.Printf("版本号: %s", versionStr)
// Run make deploy
log.Printf("开始执行make all命令...")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
defer cancel()
makeCmd := exec.CommandContext(ctx, "make")
makeCmd.Dir = buildDir
// 直接设置标准输出和错误输出
makeCmd.Stdout = os.Stdout
makeCmd.Stderr = os.Stderr
log.Printf("正在启动make 命令...")
if err := makeCmd.Start(); err != nil {
return fmt.Errorf("启动make命令失败: %v", err)
}
log.Printf("make all命令已启动开始执行...")
// 等待命令完成
if err := makeCmd.Wait(); err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
return fmt.Errorf("命令执行失败,退出码: %d", exitErr.ExitCode())
}
return fmt.Errorf("make命令执行失败: %v", err)
}
if ctx.Err() == context.DeadlineExceeded {
return fmt.Errorf("命令执行超时")
}
log.Printf("cicd执行完成")
// 发送飞书通知
if err := sendFeishuNotification(webhookURL, req, versionStr, "success", 0); err != nil {
log.Printf("发送飞书通知失败: %v", err)
} else {
log.Printf("飞书通知发送成功")
}
return nil
}
// FeishuMessage 飞书消息结构
type FeishuMessage struct {
MsgType string `json:"msg_type"`
Content struct {
Text string `json:"text"`
} `json:"content"`
}
// sendFeishuNotification 发送飞书通知
func sendFeishuNotification(webhook string, request *BuildRequest, version string, msgType string, queueLength int) error {
var messageText string
switch msgType {
case "prepare":
waitTime := queueLength * 3 // 假设每个构建大约需要3分钟
messageText = fmt.Sprintf("⌛ 构建请求已收到\n"+
"───────────────\n"+
"📦 项目: %s\n"+
"🌿 分支: %s\n"+
"📊 队列状态: 前面还有 %d 个构建请求\n"+
"⏳ 预计等待: 约 %d 分钟\n"+
"───────────────\n"+
"请耐心等待...",
request.RepoURL,
request.Branch,
queueLength,
waitTime)
case "start":
messageText = fmt.Sprintf("🏗️ 开始构建\n"+
"───────────────\n"+
"📦 项目: %s\n"+
"🌿 分支: %s\n"+
"🕐 时间: %s\n"+
"───────────────\n"+
"构建进行中...",
request.RepoURL,
request.Branch,
time.Now().Format("2006-01-02 15:04:05"))
case "success":
messageText = fmt.Sprintf("🚀 部署通知\n"+
"───────────────\n"+
"📦 项目: %s\n"+
"🌿 分支: %s\n"+
"🏷️ 版本: %s\n"+
"✨ 状态: 部署成功\n"+
"🕐 时间: %s\n"+
"───────────────\n"+
"祝您工作愉快!👨‍💻",
request.RepoURL,
request.Branch,
version,
time.Now().Format("2006-01-02 15:04:05"))
}
message := FeishuMessage{
MsgType: "text",
Content: struct {
Text string `json:"text"`
}{
Text: messageText,
},
}
jsonData, err := json.Marshal(message)
if err != nil {
return fmt.Errorf("序列化消息失败: %v", err)
}
resp, err := http.Post(webhook, "application/json", bytes.NewBuffer(jsonData))
if err != nil {
return fmt.Errorf("发送通知失败: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return fmt.Errorf("飞书API返回错误: status=%d, body=%s", resp.StatusCode, string(body))
}
return nil
}
func webhookHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
var payload struct {
Repository struct {
GitHTTPURL string `json:"git_http_url"`
} `json:"repository"`
Ref string `json:"ref"`
}
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
http.Error(w, "Failed to parse webhook payload", http.StatusBadRequest)
return
}
// Extract branch name from ref (refs/heads/master -> master)
branch := filepath.Base(payload.Ref)
// Add build request to queue
buildQueue.Add(BuildRequest{
RepoURL: payload.Repository.GitHTTPURL,
Branch: branch,
})
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "Build request queued")
}
func main() {
http.HandleFunc("/webhook", webhookHandler)
port := "29999"
log.Printf("Starting server on port %s", port)
if err := http.ListenAndServe(":"+port, nil); err != nil {
log.Fatal(err)
}
}

BIN
k8s/.DS_Store vendored Normal file

Binary file not shown.

0
k8s/Yapi/Dockerfile Normal file
View File

23
k8s/busybox.yaml Normal file
View File

@ -0,0 +1,23 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: busy-dep
name: busy-dep
namespace: wk
spec:
replicas: 1
selector:
matchLabels:
app: busy-dep
template:
metadata:
labels:
app: busy-dep
spec:
containers:
- image: ccr-29eug8s3-vpc.cnc.bj.baidubce.com/public/busybox
name: busybox
command: ["/bin/sh","-c","sleep 3600"]
nodeSelector:
disktype: ssd

View File

@ -0,0 +1,36 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: cloud-ai-project
namespace: bj2-vector
spec:
replicas: 1
selector:
matchLabels:
app: cloud-ai-project
template:
metadata:
labels:
app: cloud-ai-project
spec:
hostNetwork: true
imagePullSecrets:
- name: registry-auth
containers:
- name: cloud-ai-project
image: ccr-29eug8s3-vpc.cnc.bj.baidubce.com/service/cloud_ai_project:v6
imagePullPolicy: Always
ports:
- containerPort: 8006
securityContext:
runAsUser: 0
privileged: true
resources:
requests:
nvidia.com/gpu: 1
cpu: "1"
memory: "20Gi"
limits:
nvidia.com/gpu: 1
cpu: "1"
memory: "30Gi"

View File

@ -0,0 +1,20 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cloud-ai-ingress
namespace: bj2-vector
labels:
app: cloud-ai-project
spec:
ingressClassName: nginx
rules:
- host: cloud-test.d-robotics.cc
http:
paths:
- path: /vector
pathType: ImplementationSpecific
backend:
service:
name: cloud-api-svc
port:
number: 80

16
k8s/cloud-api/svc.yaml Normal file
View File

@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: cloud-api-svc
namespace: bj2-vector
labels:
app: cloud-ai-project
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8006
selector:
app: cloud-ai-project
type: ClusterIP

36
k8s/cvpr/deploy.yaml Normal file
View File

@ -0,0 +1,36 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: cvpr-competition-server
namespace: bj1-cvpr
labels:
app: cvpr-competition-server
spec:
replicas: 2
selector:
matchLabels:
app: cvpr-competition-server
template:
metadata:
labels:
app: cvpr-competition-server
spec:
imagePullSecrets:
- name: registry-auth
containers:
- name: cvpr-competition-server
image: ccr-29eug8s3-vpc.cnc.bj.baidubce.com/public/cvpr-competition-server:v3
ports:
- containerPort: 8080
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
env:
- name: DB_HOST
value: "mysql-prod.rdsmd4w68w703bh.rds.bj.baidubce.com"
restartPolicy: Always

18
k8s/cvpr/ingress.yaml Normal file
View File

@ -0,0 +1,18 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cvpr-competition-ingress
namespace: bj1-cvpr
spec:
ingressClassName: nginx
rules:
- host: cvpr-competition.d-robotics.cc
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: cvpr-competition-server
port:
number: 8080

12
k8s/cvpr/service.yaml Normal file
View File

@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: cvpr-competition-server
namespace: bj1-cvpr
spec:
selector:
app: cvpr-competition-server
ports:
- protocol: TCP
port: 8080
targetPort: 8080

18
k8s/ingress.yaml Normal file
View File

@ -0,0 +1,18 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ing
namespace: wk
spec:
ingressClassName: nginx
rules:
- host: nginx.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80

7
k8s/ingressClass.yaml Normal file
View File

@ -0,0 +1,7 @@
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
namespace: wk
spec:
controller: k8s.io/ingress-nginx

View File

@ -0,0 +1,27 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: d-robotics
namespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: d-robotics
subjects:
- kind: ServiceAccount
name: d-robotics
namespace: kube-system
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Secret
metadata:
name: d-robotics
namespace: kube-system
annotations:
kubernetes.io/service-account.name: "d-robotics"
type: kubernetes.io/service-account-token

View File

@ -0,0 +1,41 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: jumpserver-admin
namespace: test
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: jumpserver-admin-role
namespace: test
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps", "secrets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: jumpserver-admin-rolebinding
namespace: test
subjects:
- kind: ServiceAccount
name: jumpserver-admin
namespace: test
roleRef:
kind: Role
name: jumpserver-admin-role
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Secret
metadata:
name: jumpserver-admin
namespace: test
annotations:
kubernetes.io/service-account.name: "jumpserver-admin"
type: kubernetes.io/service-account-token

48
k8s/one-api-deploy.yaml Normal file
View File

@ -0,0 +1,48 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: one-api-deployment
spec:
replicas: 1
selector:
matchLabels:
app: one-api
template:
metadata:
labels:
app: one-api
spec:
containers:
- name: one-api
image: "ghcr.io/songquanpeng/one-api:latest"
ports:
- containerPort: 3000
env:
- name: SQL_DSN
value: "oneapi:9Qr4a4a_bpjTXHmWkD8V@tcp(mysql-prod.rdsmd4w68w703bh.rds.bj.baidubce.com:3306)/oneapi"
- name: REDIS_CONN_STRING
value: "redis://"
- name: SESSION_SECRET
value: "3*#>%YLX>@pG"
- name: TZ
value: "Asia/Shanghai"
volumeMounts:
- name: oneapi-data
mountPath: /data
volumes:
- name: oneapi-data
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: one-api-service
spec:
selector:
app: one-api
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: ClusterIP

22
k8s/one-api.yaml Normal file
View File

@ -0,0 +1,22 @@
services:
one-api:
image: "ghcr.io/songquanpeng/one-api:latest"
container_name: ghs-one-api
restart: unless-stopped
# command: --log-dir /app/logs
ports:
- "3000:3000"
volumes:
- ./data/oneapi:/data
environment:
- SQL_DSN=oneapi:9Qr4a4a_bpjTXHmWkD8V@tcp(mysql-prod.rdsmd4w68w703bh.rds.bj.baidubce.com:3306)/oneapi
- REDIS_CONN_STRING=redis://redis
- SESSION_SECRET=3*#>%YLX>@pG
- TZ=Asia/Shanghai
depends_on:
- redis
healthcheck:
test: [ "CMD-SHELL", "wget -q -O - http://localhost:3000/api/status | grep -o '\"success\":\\s*true' | awk -F: '{print $2}'" ]
interval: 60s
timeout: 10s
retries: 3

35
k8s/one-api/deploy.yaml Normal file
View File

@ -0,0 +1,35 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: one-api-deployment
namespace: bj1-dcloud
spec:
replicas: 1
selector:
matchLabels:
app: one-api
template:
metadata:
labels:
app: one-api
spec:
containers:
- name: one-api
image: ccr-29eug8s3-vpc.cnc.bj.baidubce.com/public/one-api:latest
ports:
- containerPort: 3000
env:
- name: SQL_DSN
value: "oneapi:9Qr4a4a_bpjTXHmWkD8V@tcp(mysql-prod.rdsmd4w68w703bh.rds.bj.baidubce.com:3306)/oneapi"
- name: REDIS_CONN_STRING
value: "onr-api://lv8zcY^Xj)96@redis.uqthtfjpcagp.scs.bj.baidubce.com:6379"
- name: SESSION_SECRET
value: "3*#>%YLX>@pG"
- name: TZ
value: "Asia/Shanghai"
volumeMounts:
- name: oneapi-data
mountPath: /data
volumes:
- name: oneapi-data
emptyDir: {}

18
k8s/one-api/ingress.yml Normal file
View File

@ -0,0 +1,18 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: one-api-ingress
namespace: bj1-dcloud
spec:
ingressClassName: nginx
rules:
- host: llmproxy.d-robotics.cc # 替换为你的域名
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: one-api-service
port:
number: 80

13
k8s/one-api/svc.yaml Normal file
View File

@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: one-api-service
namespace: bj1-dcloud
spec:
selector:
app: one-api
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: ClusterIP

View File

@ -0,0 +1,27 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: backend-config
namespace: bj2-copilot
data:
.env: |
CURRENT_ENV = "测试环境"
COPILOT_SERVER_MONITOR_FEISHU_NOTICE_WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/edb14958-6566-41d2-86b6-4981efe06d45"
COPILOT_SERVER_MONITOR_FEISHU_NOTICE_COOKIE="QXV0aHpDb250ZXh0=a1a7227498d04ff49920e4a150350f1a; passport_web_did=7176225323518902274"
CODE_GEE_X_ENDPOINT = "http://120.48.158.165:8901/v1/chat/completions"
CODE_GEE_X_MODEL_NAME = "/codegeex4-all-9b"
DB_HOST="mysql1.rdsmbk3ednsgnnt.rds.bj.baidubce.com"
DB_PORT="3306"
DB_NAME="rdk_copilot_dev"
DB_USER="rdk_copilot"
DB_PASSWORD="tol_Ck1@3fqa"
BAIDU_MOCHOW_ACCOUNT="root"
BAIDU_MOCHOW_API_KEY="vdb$t7te2t5nn5n"
BAIDU_MOCHOW_ENDPOINT="http://180.76.107.178:5287"
BAIDU_QIANFAN_API_KEY = "PO7E1BhAXAJbEYeCCZuYDKHH"
BAIDU_QIANFAN_SECRET_KEY = "HFurKwTrUfXvCZZIAG6hnpK4tqBpXlrL"
CMS_BASE_URL= http://cloud-test.d-robotics.cc
RDK_DOC_BASE_URL="https://developer.d-robotics.cc/"
AZURE_OPENAI_API_KEY = "d4fe0f5d07e24f049685decfd98adc98"
AZURE_OPENAI_ENDPOINT = "https://embodiedai.openai.azure.com"
AZURE_API_VERSION = "2023-12-01-preview"

View File

@ -0,0 +1,18 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: backend-ingress
namespace: bj2-copilot
spec:
ingressClassName: nginx
rules:
- host: copilotdev.d-robotics.cc
http:
paths:
- path: /llm(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: backend-svc
port:
number: 80

View File

@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: backend-svc
namespace: bj2-copilot
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8001
selector:
app.kubernetes.io/name: rdkcopilot-backend
type: ClusterIP

View File

@ -0,0 +1,43 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: rdkcopilot-backend-dc84951
namespace: bj2-copilot
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: rdkcopilot-backend
template:
metadata:
labels:
app.kubernetes.io/name: rdkcopilot-backend
spec:
containers:
- name: backend
image: ccr-29eug8s3-vpc.cnc.bj.baidubce.com/traint_cloud_disk/rdkcopilot-backend:130e6be
imagePullPolicy: Always
ports:
- containerPort: 8001
resources:
limits:
cpu: 200m
ephemeral-storage: 100Mi
memory: 400Mi
requests:
cpu: 200m
ephemeral-storage: 100Mi
memory: 400Mi
volumeMounts:
- mountPath: /data/log
name: log-dir
- mountPath: /ws/src/.env
name: config
subPath: .env
volumes:
- emptyDir: {}
name: log-dir
- configMap:
defaultMode: 420
name: backend-config
name: config

View File

@ -0,0 +1,26 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: rdk-monitor
namespace: monitoring
labels:
app: rdk-monitor
spec:
replicas: 1
selector:
matchLabels:
app: rdk-monitor
template:
metadata:
labels:
app: rdk-monitor
spec:
containers:
- name: rdk-monitor-container
image: ccr-29eug8s3-vpc.cnc.bj.baidubce.com/public/rdk-moniter:v1
args:
- "3"
- "https://copilot.d-robotics.cc/llm/rdkCopilotApi/v1/monitor/health_check"
- "https://open.feishu.cn/open-apis/bot/v2/hook/edb14958-6566-41d2-86b6-4981efe06d45"
imagePullPolicy: Always

View File

@ -0,0 +1,27 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: rdk-monitor
namespace: monitoring
labels:
app: rdk-monitor
spec:
replicas: 1
selector:
matchLabels:
app: rdk-monitor
template:
metadata:
labels:
app: rdk-monitor
spec:
containers:
- name: rdk-monitor-container
image: ccr-29eug8s3-vpc.cnc.bj.baidubce.com/service/rdk-moniter:v1
args:
- "3"
- "https://copilot.d-robotics.cc/llm/rdkCopilotApi/v1/monitor/health_check"
- "https://open.feishu.cn/open-apis/bot/v2/hook/edb14958-6566-41d2-86b6-4981efe06d45"
imagePullPolicy: Always
imagePullSecrets:
- name: trainer-cloud-disk-secret

View File

@ -0,0 +1,25 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: rdk-monitor-dev
namespace: monitoring
labels:
app: rdk-monitor-dev
spec:
replicas: 1
selector:
matchLabels:
app: rdk-monitor-dev
template:
metadata:
labels:
app: rdk-monitor-dev
spec:
containers:
- name: rdk-monitor-container-dev
image: ccr-29eug8s3-vpc.cnc.bj.baidubce.com/public/rdk-moniter:v1
args:
- "3"
- "https://copilotdev.d-robotics.cc/llm/rdkCopilotApi/v1/monitor/health_check"
- "https://open.feishu.cn/open-apis/bot/v2/hook/edb14958-6566-41d2-86b6-4981efe06d45"
imagePullPolicy: Always

59
passwd/main/main.go Normal file
View File

@ -0,0 +1,59 @@
package main
import (
"fmt"
"math/rand"
"os"
"time"
)
// 定义包含大小写字母、数字、特殊符号的字符集
const charset = "abcdefghijklmnopqrstuvwxyz" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" +
"!@#$%^*()"
// 生成指定长度的随机字符串
func generateRandomString(length int) string {
// 初始化随机数种子
rand.Seed(time.Now().UnixNano())
// 用于存储生成的随机字符串
b := make([]byte, length)
// 遍历指定长度,从字符集中随机选取字符添加到结果中
for i := range b {
b[i] = charset[rand.Intn(len(charset))]
}
return string(b)
}
// 将内容追加到文件中
func appendToFile(filePath string, content string) error {
// 以追加和创建文件的模式打开文件
file, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return err
}
// 确保文件在函数结束时关闭
defer file.Close()
// 向文件中写入内容并添加换行符
_, err = file.WriteString(content + "\n")
return err
}
func main() {
// 调用函数生成 32 位的随机密码
password := generateRandomString(32)
fmt.Println("生成的 32 位密码是:", password)
// 定义要写入的文件路径
filePath := "/Users/d-robotics/dep/passwd/passwd.txt"
// 调用函数将密码追加到文件中
err := appendToFile(filePath, password)
if err != nil {
fmt.Printf("写入文件时出错: %v\n", err)
} else {
fmt.Printf("密码已成功追加到 %s 文件中。\n", filePath)
}
}

26
passwd/passwd.txt Normal file
View File

@ -0,0 +1,26 @@
p5}C;(.QJ0LcB*h..}(AU3|-^bd?Y:lR
7=x]b*l/gDZUPP7DMf,asz+s6UmA(A.U
aFgAv<}=/e8qi]!,Yz}:TjE]K%6qPwLx
>viXEJ|W^RzS^Nt+Zle_Z@leTdm?D-sV
w5i39_|h4crl]XS]E)RG!h00L|&1>'bi
a3Hl(wuEqngwauJY
XR8qu9mh^9Leg5iJ
iLth@y3XR7zryFaSfxLph@Cxp8NEz5eL
gr2M#7uP$SoV%sF7*5w8U(A8niEijUrl
T^9Muu%(rDQwb(#GIkfJ$s$h#9VrPEw@
0Uf9FbijlbmEm3BeuAhfmT$XjsO$KgB8
k69ujNYyNRTkGY0w9)81rjRu$1Mfl#W1
yvthnfO73sR9!
6HSw(cryvI3v$3eICkNpK0dy0)QpWsgZ
BpwdZgEU9w)EUCCeEfxDMZpDrLb444)%
uRC0EKTFm*4
lv8zcY^Xj)96
jZ7*HmD8*hkQeYAw!*!xwAFGF@)y5F51
aJ3R1$gzSr!^)*kH1G7jhQNk3Ih^4gpn
qzRaNjS$WusViUeT2VQaZvE4jPj0u9Pu
lrTaejEGXRihN*p@Sf)p06e2XDSexxUP
jzNI0bq2Ju%cwZzysbrmV1XEAZ0%))M5
dZF7jbXVS3QqDbooxO3uJQKqDRg$FHKL
vnCzJ@r09aXQzka4oycH@hi32y#yXC8$
u()XONJf2PgyQM

39
passwd/useradd.sh Normal file
View File

@ -0,0 +1,39 @@
#!/bin/bash
username=$1
homedir="/data/"
num=1
check_command() {
if [ $? -ne 0 ]; then
let num = $num + 1
exit 1 # 退出脚本并返回错误状态
fi
}
mkdir -p $homedir/$usernames
check_command
chown -R $username:$username $homedir/$username
check_command
useradd -m -d $homedir/$username -s /bin/bash $username
check_command
password= $(openssl rand -base64 48 | cut -c1-6)
echo "$password" | passwd --stdin $username
check_command
chown -R $username:$username $homedir/$username
check_command
usermod -aG docker $username
check_command
newgrp docker
check_command
read -p "是否需要sudo权限(y/n):" yn
if [ $yn = "是" ]; then
usermod -aG sudo $username
fi
echo "用户创建成功!"
echo "================================================================"
IP=$(curl ifconfig.me)
echo "公网IP$IP"
ip=$(hostname -I)
echo "内网IP(默认使用第一个)$ip"
echo "用户名:$username"
echo "密码:$password"