!94 实现devstar可以在对应配置的k8s上添加和删除runner
* 修复runners.go中关于ctx的编译报错 * Merge branch 'main' of gitee.com:devstar/devstar into feature/runner * 实现devstar可以在对应配置的k8s上添加和删除runner * 实现了修改runner的标签的功能 * 单机部署环境下实现Web界面上启动和删除runner * 启动时能够自动启动act_runner
This commit is contained in:
repo.diff.committed_by
孟宁
repo.diff.parent
68512a67c8
repo.diff.commit
b9ff967366
31
go.mod
31
go.mod
@@ -134,6 +134,34 @@ require (
|
||||
xorm.io/xorm v1.3.9
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
|
||||
github.com/distribution/reference v0.5.0 // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/google/gnostic-models v0.6.9 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
golang.org/x/term v0.32.0 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
k8s.io/apimachinery v0.33.3 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
|
||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/compute/metadata v0.6.0 // indirect
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
@@ -190,6 +218,7 @@ require (
|
||||
github.com/davidmz/go-pageant v1.0.2 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dlclark/regexp2 v1.11.5 // indirect
|
||||
github.com/docker/docker v24.0.9+incompatible
|
||||
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
|
||||
@@ -279,6 +308,8 @@ require (
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250422160041-2d3770c4ea7f // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
k8s.io/api v0.33.3
|
||||
k8s.io/client-go v0.33.3
|
||||
)
|
||||
|
||||
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1
|
||||
|
||||
66
go.sum
66
go.sum
@@ -60,6 +60,8 @@ github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 h1:D3occ
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0/go.mod h1:bTSOgj05NGRuHHhQwAdPnYr9TOdNmKlZTgGLL6nyAdI=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.0 h1:UXT0o77lXQrikd1kgwIPQOUect7EoR/+sbP4wQKdzxM=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.0/go.mod h1:cTvi54pg19DoT07ekoeMgE/taAwNtCShVeZqA+Iv2xI=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs=
|
||||
@@ -238,6 +240,8 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21 h1:PdsjTl0Cg+ZJgOx/CFV5NNgO1ThTreqdgKYiDCMHJwA=
|
||||
github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21/go.mod h1:xJvkyD6Y2rZapGvPJLYo9dyx1s5dxBEDPa8T3YTuOk0=
|
||||
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
|
||||
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/djherbis/buffer v1.1.0/go.mod h1:VwN8VdFkMY0DCALdY8o00d3IZ6Amz/UNVMWcSaJT44o=
|
||||
github.com/djherbis/buffer v1.2.0 h1:PH5Dd2ss0C7CRRhQCZ2u7MssF+No9ide8Ye71nPHcrQ=
|
||||
github.com/djherbis/buffer v1.2.0/go.mod h1:fjnebbZjCUpPinBRD+TDwXSOeNQ7fPQWLfGQqiAiUyE=
|
||||
@@ -248,6 +252,14 @@ github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55k
|
||||
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
|
||||
github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0=
|
||||
github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY=
|
||||
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s=
|
||||
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
|
||||
@@ -266,6 +278,8 @@ github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTe
|
||||
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 h1:oP4q0fw+fOSWn3DfFi4EXdT+B+gTtzx8GC9xsc26Znk=
|
||||
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
|
||||
github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||
github.com/ethantkoenig/rupture v1.0.1 h1:6aAXghmvtnngMgQzy7SMGdicMvkV86V4n9fT0meE5E4=
|
||||
@@ -321,6 +335,16 @@ github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
||||
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-ldap/ldap/v3 v3.4.11 h1:4k0Yxweg+a3OyBLjdYn5OKglv18JNvfDykSoI8bW0gU=
|
||||
github.com/go-ldap/ldap/v3 v3.4.11/go.mod h1:bY7t0FLK8OAVpp/vV6sSlpz3EQDGcQwc8pF0ujLgKvM=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
||||
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
|
||||
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-redis/redis/v7 v7.4.1 h1:PASvf36gyUpr2zdOUS/9Zqc80GbM+9BDyiJSJDDOrTI=
|
||||
@@ -345,6 +369,8 @@ github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm
|
||||
github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f h1:3BSP1Tbs2djlpprl7wCLuiqMaUh5SJkkzI2gDs+FgLs=
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14=
|
||||
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 h1:UjoPNDAQ5JPCjlxoJd6K8ALZqSDDhk2ymieAZOVaDg0=
|
||||
@@ -382,11 +408,14 @@ github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl76
|
||||
github.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q=
|
||||
github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
|
||||
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
@@ -478,6 +507,8 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
@@ -545,11 +576,15 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd h1:aY7OQNf2XqY/JQ6qREWamhI/81os/agb2BAGpcx5yWI=
|
||||
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 h1:j2kD3MT1z4PXCiUllUJF9mWUESr9TWKS7iEKsQ/IipM=
|
||||
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450/go.mod h1:skjdDftzkFALcuGzYSklqYd8gvat6F1gZJ4YPVbkZpM=
|
||||
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
|
||||
@@ -726,6 +761,7 @@ github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3i
|
||||
github.com/yohcop/openid-go v1.0.1 h1:DPRd3iPO5F6O5zX2e62XpVAbPT6wV51cuucH0z9g3js=
|
||||
github.com/yohcop/openid-go v1.0.1/go.mod h1:b/AvD03P0KHj4yuihb+VtLD6bYYgsy0zqBzPCRjkCNs=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
@@ -846,6 +882,7 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -893,8 +930,10 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200928182047-19e03678916f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
@@ -923,7 +962,11 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
@@ -941,6 +984,20 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||
k8s.io/api v0.33.3 h1:SRd5t//hhkI1buzxb288fy2xvjubstenEKL9K51KBI8=
|
||||
k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE=
|
||||
k8s.io/apimachinery v0.33.3 h1:4ZSrmNa0c/ZpZJhAgRdcsFcZOw1PQU1bALVQ0B3I5LA=
|
||||
k8s.io/apimachinery v0.33.3/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
|
||||
k8s.io/client-go v0.33.3 h1:M5AfDnKfYmVJif92ngN532gFqakcGi6RvaOF16efrpA=
|
||||
k8s.io/client-go v0.33.3/go.mod h1:luqKBQggEf3shbxHY4uVENAxrDISLOarxpTKMiUuujg=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4=
|
||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8=
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
||||
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
|
||||
@@ -965,6 +1022,15 @@ mvdan.cc/xurls/v2 v2.6.0 h1:3NTZpeTxYVWNSokW3MKeyVkz/j7uYXYiMtXRUfmjbgI=
|
||||
mvdan.cc/xurls/v2 v2.6.0/go.mod h1:bCvEZ1XvdA6wDnxY7jPPjEmigDtvtvPXAD/Exa9IMSk=
|
||||
pgregory.net/rapid v0.4.2 h1:lsi9jhvZTYvzVpeG93WWgimPRmiJQfGFRNTEZh1dtY0=
|
||||
pgregory.net/rapid v0.4.2/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU=
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
|
||||
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
||||
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
|
||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 h1:mUcz5b3FJbP5Cvdq7Khzn6J9OCUQJaBwgBkCR+MOwSs=
|
||||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:FJGmPh3vz9jSos1L/F91iAgnC/aejc0wIIrF2ZwJxdY=
|
||||
xorm.io/builder v0.3.13 h1:a3jmiVVL19psGeXx8GIurTp7p0IIgqeDmwhcR6BAOAo=
|
||||
|
||||
117
modules/docker/docker_api.go
Normal file
117
modules/docker/docker_api.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/client"
|
||||
)
|
||||
|
||||
// CreateDockerClient 创建Docker客户端
|
||||
func CreateDockerClient(ctx context.Context) (*client.Client, error) {
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cli, nil
|
||||
}
|
||||
|
||||
// GetDockerSocketPath 获取Docker Socket路径
|
||||
func GetDockerSocketPath() (string, error) {
|
||||
// 检查常见的Docker socket路径
|
||||
socketPaths := []string{
|
||||
"/var/run/docker.sock",
|
||||
"/run/podman/podman.sock",
|
||||
"$HOME/.colima/docker.sock",
|
||||
"$XDG_RUNTIME_DIR/docker.sock",
|
||||
"$XDG_RUNTIME_DIR/podman/podman.sock",
|
||||
`\\.\pipe\docker_engine`,
|
||||
"$HOME/.docker/run/docker.sock",
|
||||
}
|
||||
|
||||
for _, path := range socketPaths {
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
return path, nil
|
||||
}
|
||||
}
|
||||
|
||||
// 如果找不到,返回默认路径
|
||||
return "/var/run/docker.sock", nil
|
||||
}
|
||||
|
||||
// PullImage 拉取Docker镜像
|
||||
func PullImage(cli *client.Client, dockerHost, imageName string) error {
|
||||
ctx := context.Background()
|
||||
|
||||
reader, err := cli.ImagePull(ctx, imageName, types.ImagePullOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
// 读取并丢弃输出,确保拉取完成
|
||||
_, err = io.Copy(io.Discard, reader)
|
||||
return err
|
||||
}
|
||||
|
||||
// CreateAndStartContainer 创建并启动容器
|
||||
func CreateAndStartContainer(cli *client.Client, imageName string, cmd []string, env []string, binds []string, ports map[string]string, containerName string) error {
|
||||
ctx := context.Background()
|
||||
|
||||
// 配置容器
|
||||
config := &container.Config{
|
||||
Image: imageName,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
if cmd != nil {
|
||||
config.Cmd = cmd
|
||||
}
|
||||
|
||||
hostConfig := &container.HostConfig{
|
||||
Binds: binds,
|
||||
}
|
||||
|
||||
// 如果有端口映射配置
|
||||
if ports != nil && len(ports) > 0 {
|
||||
// 这里可以根据需要添加端口映射逻辑
|
||||
// hostConfig.PortBindings = portBindings
|
||||
}
|
||||
|
||||
// 创建容器
|
||||
resp, err := cli.ContainerCreate(ctx, config, hostConfig, nil, nil, containerName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 启动容器
|
||||
return cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{})
|
||||
}
|
||||
|
||||
// DeleteContainer 停止并删除指定名称的容器
|
||||
func DeleteContainer(cli *client.Client, containerName string) error {
|
||||
ctx := context.Background()
|
||||
|
||||
// 首先尝试停止容器
|
||||
timeout := 10
|
||||
err := cli.ContainerStop(ctx, containerName, container.StopOptions{
|
||||
Timeout: &timeout,
|
||||
})
|
||||
if err != nil {
|
||||
// 如果容器已经停止或不存在,继续执行删除操作
|
||||
// 这里不返回错误,因为我们的目标是删除容器
|
||||
}
|
||||
|
||||
// 删除容器
|
||||
err = cli.ContainerRemove(ctx, containerName, types.ContainerRemoveOptions{
|
||||
Force: true, // 强制删除,即使容器正在运行
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
14
modules/setting/k8s.go
Normal file
14
modules/setting/k8s.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package setting
|
||||
|
||||
var K8sConfig = struct {
|
||||
Enable bool
|
||||
Url string
|
||||
Token string
|
||||
}{}
|
||||
|
||||
func loadK8sSettingsFrom(rootCfg ConfigProvider) {
|
||||
sec := rootCfg.Section("k8s")
|
||||
K8sConfig.Enable = sec.Key("ENABLE").MustBool(false)
|
||||
K8sConfig.Url = sec.Key("URL").MustString("")
|
||||
K8sConfig.Token = sec.Key("TOKEN").MustString("")
|
||||
}
|
||||
14
modules/setting/runners.go
Normal file
14
modules/setting/runners.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package setting
|
||||
|
||||
var Runner = struct {
|
||||
AutoStart bool
|
||||
Count int
|
||||
Image string
|
||||
}{}
|
||||
|
||||
func loadRunnerSettingsFrom(rootCfg ConfigProvider) {
|
||||
sec := rootCfg.Section("runners")
|
||||
Runner.AutoStart = sec.Key("AUTO_START").MustBool(true)
|
||||
Runner.Count = sec.Key("RUNNER_COUNT").MustInt(1)
|
||||
Runner.Image = sec.Key("RUNNER_IMAGE").MustString("devstar.cn/devstar/act_runner:latest")
|
||||
}
|
||||
@@ -217,6 +217,8 @@ func LoadSettings() {
|
||||
loadProjectFrom(CfgProvider)
|
||||
loadMimeTypeMapFrom(CfgProvider)
|
||||
loadFederationFrom(CfgProvider)
|
||||
loadRunnerSettingsFrom(CfgProvider)
|
||||
loadK8sSettingsFrom(CfgProvider)
|
||||
loadWechatSettingsFrom(CfgProvider)
|
||||
}
|
||||
|
||||
@@ -225,6 +227,8 @@ func LoadSettingsForInstall() {
|
||||
loadDBSetting(CfgProvider)
|
||||
loadServiceFrom(CfgProvider)
|
||||
loadMailerFrom(CfgProvider)
|
||||
loadRunnerSettingsFrom(CfgProvider)
|
||||
loadK8sSettingsFrom(CfgProvider)
|
||||
loadWechatSettingsFrom(CfgProvider)
|
||||
}
|
||||
|
||||
|
||||
@@ -303,6 +303,10 @@ log_root_path = Log Path
|
||||
log_root_path_helper = Log files will be written to this directory.
|
||||
|
||||
optional_title = Optional Settings
|
||||
k8s_title = Kubernetes Settings
|
||||
k8s_enable = Enable Kubernetes
|
||||
k8s_url = Kubernetes API URL
|
||||
k8s_token = Kubernetes Token
|
||||
email_title = Email Settings
|
||||
smtp_addr = SMTP Host
|
||||
smtp_port = SMTP Port
|
||||
@@ -3879,6 +3883,8 @@ runners.status.active = Active
|
||||
runners.status.offline = Offline
|
||||
runners.version = Version
|
||||
runners.reset_registration_token = Reset registration token
|
||||
runners.regist_runner = Register a new runner
|
||||
runners.regist_runner_success = Register a new runner successfully
|
||||
runners.reset_registration_token_confirm = Would you like to invalidate the current token and generate a new one?
|
||||
runners.regist_runner = Register a new runner
|
||||
runners.regist_runner_success = Register a new runner successfully
|
||||
|
||||
@@ -298,6 +298,10 @@ log_root_path=日志路径
|
||||
log_root_path_helper=日志文件将写入此目录。
|
||||
|
||||
optional_title=可选设置
|
||||
k8s_title = Kubernetes设置
|
||||
k8s_enable = 启用 Kubernetes
|
||||
k8s_url = Kubernetes API 地址
|
||||
k8s_token = Kubernetes 访问令牌
|
||||
email_title=电子邮箱设置
|
||||
smtp_addr=SMTP 主机地址
|
||||
smtp_port=SMTP 端口
|
||||
@@ -3866,6 +3870,8 @@ runners.status.active=启用
|
||||
runners.status.offline=离线
|
||||
runners.version=版本
|
||||
runners.reset_registration_token=重置注册令牌
|
||||
runners.regist_runner=启动并注册一个运行器
|
||||
runners.regist_runner_success=成功启动并注册一个运行器
|
||||
runners.reset_registration_token_confirm=是否吊销当前令牌并生成一个新令牌?
|
||||
runners.regist_runner=启动并注册一个运行器
|
||||
runners.regist_runner_success=成功启动并注册一个运行器
|
||||
|
||||
@@ -36,6 +36,7 @@ import (
|
||||
auth_service "code.gitea.io/gitea/services/auth"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
runners_service "code.gitea.io/gitea/services/runners"
|
||||
"code.gitea.io/gitea/services/versioned_migration"
|
||||
|
||||
"gitea.com/go-chi/session"
|
||||
@@ -123,6 +124,10 @@ func Install(ctx *context.Context) {
|
||||
form.AppURL = setting.AppURL
|
||||
form.LogRootPath = setting.Log.RootPath
|
||||
|
||||
form.K8sEnable = setting.K8sConfig.Enable
|
||||
form.K8sUrl = setting.K8sConfig.Url
|
||||
form.K8sToken = setting.K8sConfig.Token
|
||||
|
||||
// E-mail service settings
|
||||
if setting.MailService != nil {
|
||||
form.SMTPAddr = setting.MailService.SMTPAddr
|
||||
@@ -450,6 +455,20 @@ func SubmitInstall(ctx *context.Context) {
|
||||
cfg.Section("wechat").Key("ENABLED_WECHAT_QR_SIGNIN").SetValue("false")
|
||||
}
|
||||
|
||||
if form.K8sEnable {
|
||||
ctx.Data["K8sEnable"] = form.K8sEnable
|
||||
cfg.Section("k8s").Key("ENABLE").SetValue("true")
|
||||
cfg.Section("k8s").Key("URL").SetValue(form.K8sUrl)
|
||||
cfg.Section("k8s").Key("TOKEN").SetValue(form.K8sToken)
|
||||
} else {
|
||||
ctx.Data["K8sEnable"] = form.K8sEnable
|
||||
cfg.Section("k8s").Key("ENABLE").SetValue("false")
|
||||
}
|
||||
|
||||
cfg.Section("runners").Key("AUTO_START").SetValue("true")
|
||||
cfg.Section("runners").Key("RUNNER_COUNT").SetValue("1")
|
||||
cfg.Section("runners").Key("RUNNER_IMAGE").SetValue("devstar.cn/devstar/act_runner:latest")
|
||||
|
||||
cfg.Section("openid").Key("ENABLE_OPENID_SIGNIN").SetValue(strconv.FormatBool(form.EnableOpenIDSignIn))
|
||||
cfg.Section("openid").Key("ENABLE_OPENID_SIGNUP").SetValue(strconv.FormatBool(form.EnableOpenIDSignUp))
|
||||
cfg.Section("service").Key("DISABLE_REGISTRATION").SetValue(strconv.FormatBool(form.DisableRegistration))
|
||||
@@ -594,6 +613,8 @@ func SubmitInstall(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
runners_service.RegistGlobalRunner(ctx)
|
||||
|
||||
setting.ClearEnvConfigKeys()
|
||||
log.Info("First-time run install finished!")
|
||||
InstallDone(ctx)
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
actions_model "code.gitea.io/gitea/models/actions"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
@@ -18,6 +19,7 @@ import (
|
||||
shared_user "code.gitea.io/gitea/routers/web/shared/user"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
runners_services "code.gitea.io/gitea/services/runners"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -253,6 +255,13 @@ func RunnersEditPost(ctx *context.Context) {
|
||||
runner.Description = form.Description
|
||||
|
||||
err = actions_model.UpdateRunner(ctx, runner, "description")
|
||||
agentLabelsStr := ctx.Req.FormValue("agentlabels")
|
||||
form.AgentLabels = strings.Split(agentLabelsStr, ",")
|
||||
for i := range form.AgentLabels {
|
||||
form.AgentLabels[i] = strings.TrimSpace(form.AgentLabels[i])
|
||||
}
|
||||
runner.AgentLabels = form.AgentLabels
|
||||
err = actions_model.UpdateRunner(ctx, runner, "description", "agent_labels")
|
||||
if err != nil {
|
||||
log.Warn("RunnerDetailsEditPost.UpdateRunner failed: %v, url: %s", err, ctx.Req.URL)
|
||||
ctx.Flash.Warning(ctx.Tr("actions.runners.update_runner_failed"))
|
||||
@@ -285,6 +294,31 @@ func ResetRunnerRegistrationToken(ctx *context.Context) {
|
||||
ctx.JSONRedirect(redirectTo)
|
||||
}
|
||||
|
||||
func RegisterARunner(ctx *context.Context) {
|
||||
rCtx, err := getRunnersCtx(ctx)
|
||||
if err != nil {
|
||||
ctx.ServerError("getRunnersCtx", err)
|
||||
return
|
||||
}
|
||||
token, err := actions_model.NewRunnerToken(ctx, rCtx.OwnerID, rCtx.RepoID)
|
||||
if err != nil {
|
||||
ctx.ServerError("NewRunnerToken", err)
|
||||
return
|
||||
}
|
||||
regToken := token.Token
|
||||
requestCtx := ctx.Req.Context()
|
||||
err = runners_services.RegistRunner(requestCtx, regToken)
|
||||
if err != nil {
|
||||
log.Warn("RegistRunner failed: %v, url: %s", err, ctx.Req.URL)
|
||||
ctx.Flash.Warning(ctx.Tr("actions.runners.regist_runner_failed"))
|
||||
ctx.Redirect(rCtx.RedirectLink)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("actions.runners.regist_runner_success"))
|
||||
ctx.Redirect(rCtx.RedirectLink)
|
||||
}
|
||||
|
||||
// RunnerDeletePost response for deleting runner
|
||||
func RunnerDeletePost(ctx *context.Context) {
|
||||
rCtx, err := getRunnersCtx(ctx)
|
||||
@@ -306,6 +340,17 @@ func RunnerDeletePost(ctx *context.Context) {
|
||||
successRedirectTo := rCtx.RedirectLink
|
||||
failedRedirectTo := rCtx.RedirectLink + url.PathEscape(ctx.PathParam("runnerid"))
|
||||
|
||||
// 删除对应的Docker容器
|
||||
if runner.Name != "" {
|
||||
requestCtx := ctx.Req.Context()
|
||||
if err := runners_services.DeleteRunnerByName(requestCtx, runner.Name); err != nil {
|
||||
log.Warn("DeleteRunnerByName failed: %v, runner name: %s, url: %s", err, runner.Name, ctx.Req.URL)
|
||||
// 即使删除容器失败,我们仍然继续删除数据库记录
|
||||
} else {
|
||||
log.Info("Successfully deleted Docker container for runner: %s", runner.Name)
|
||||
}
|
||||
}
|
||||
|
||||
if err := actions_model.DeleteRunner(ctx, runner.ID); err != nil {
|
||||
log.Warn("DeleteRunnerPost.UpdateRunner failed: %v, url: %s", err, ctx.Req.URL)
|
||||
ctx.Flash.Warning(ctx.Tr("actions.runners.delete_runner_failed"))
|
||||
|
||||
@@ -473,6 +473,16 @@ func registerWebRoutes(m *web.Router) {
|
||||
})
|
||||
}
|
||||
|
||||
addSettingsRunnersRegRoutes := func() {
|
||||
m.Group("/runners", func() {
|
||||
m.Get("", shared_actions.Runners)
|
||||
m.Combo("/{runnerid}").Get(shared_actions.RunnersEdit).
|
||||
Post(web.Bind(forms.EditRunnerForm{}), shared_actions.RunnersEditPost)
|
||||
m.Post("/{runnerid}/delete", shared_actions.RunnerDeletePost)
|
||||
m.Get("/regist_runner", shared_actions.RegisterARunner)
|
||||
})
|
||||
}
|
||||
|
||||
// FIXME: not all routes need go through same middleware.
|
||||
// Especially some AJAX requests, we can reduce middleware number to improve performance.
|
||||
|
||||
@@ -668,6 +678,7 @@ func registerWebRoutes(m *web.Router) {
|
||||
m.Group("/actions", func() {
|
||||
m.Get("", user_setting.RedirectToDefaultSetting)
|
||||
addSettingsRunnersRoutes()
|
||||
addSettingsRunnersRegRoutes()
|
||||
addSettingsSecretsRoutes()
|
||||
addSettingsVariablesRoutes()
|
||||
}, actions.MustEnableActions)
|
||||
@@ -823,6 +834,7 @@ func registerWebRoutes(m *web.Router) {
|
||||
m.Group("/actions", func() {
|
||||
m.Get("", admin.RedirectToDefaultSetting)
|
||||
addSettingsRunnersRoutes()
|
||||
addSettingsRunnersRegRoutes()
|
||||
addSettingsVariablesRoutes()
|
||||
})
|
||||
}, adminReq, ctxDataSet("EnableOAuth2", setting.OAuth2.Enabled, "EnablePackages", setting.Packages.Enabled))
|
||||
@@ -971,6 +983,7 @@ func registerWebRoutes(m *web.Router) {
|
||||
m.Group("/actions", func() {
|
||||
m.Get("", org_setting.RedirectToDefaultSetting)
|
||||
addSettingsRunnersRoutes()
|
||||
addSettingsRunnersRegRoutes()
|
||||
addSettingsSecretsRoutes()
|
||||
addSettingsVariablesRoutes()
|
||||
}, actions.MustEnableActions)
|
||||
@@ -1163,6 +1176,7 @@ func registerWebRoutes(m *web.Router) {
|
||||
m.Group("/actions", func() {
|
||||
m.Get("", shared_actions.RedirectToDefaultSetting)
|
||||
addSettingsRunnersRoutes()
|
||||
addSettingsRunnersRegRoutes()
|
||||
addSettingsSecretsRoutes()
|
||||
addSettingsVariablesRoutes()
|
||||
}, actions.MustEnableActions)
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
// EditRunnerForm form for admin to create runner
|
||||
type EditRunnerForm struct {
|
||||
Description string
|
||||
AgentLabels []string
|
||||
}
|
||||
|
||||
// Validate validates form fields
|
||||
|
||||
@@ -37,6 +37,10 @@ type InstallForm struct {
|
||||
AppURL string `binding:"Required"`
|
||||
LogRootPath string `binding:"Required"`
|
||||
|
||||
K8sEnable bool
|
||||
K8sUrl string
|
||||
K8sToken string
|
||||
|
||||
SMTPAddr string
|
||||
SMTPPort string
|
||||
SMTPFrom string
|
||||
|
||||
435
services/runners/runners.go
Normal file
435
services/runners/runners.go
Normal file
@@ -0,0 +1,435 @@
|
||||
package runners
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
actions_module "code.gitea.io/gitea/models/actions"
|
||||
docker_module "code.gitea.io/gitea/modules/docker"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
func RegistGlobalRunner(ctx context.Context) error {
|
||||
log.Info("获取全局RunnerToken...")
|
||||
actionRunnerToken, err := actions_module.NewRunnerToken(ctx, 0, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取全局RunnerToken失败:%v", err)
|
||||
}
|
||||
runnerCount := setting.Runner.Count
|
||||
for i := 0; i < runnerCount; i++ {
|
||||
err := RegistRunner(ctx, actionRunnerToken.Token)
|
||||
if err != nil {
|
||||
return fmt.Errorf("注册Runner失败:%v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkK8sIsEnable() bool {
|
||||
return setting.K8sConfig.Enable
|
||||
}
|
||||
|
||||
func RegistRunner(ctx context.Context, token string) error {
|
||||
log.Info("开始注册Runner...")
|
||||
var err error
|
||||
if checkK8sIsEnable() {
|
||||
err = registK8sRunner(ctx, token)
|
||||
} else {
|
||||
err = registDockerRunner(ctx, token)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("注册Runner失败:%v", err)
|
||||
}
|
||||
log.Info("Runner注册成功: %s", token)
|
||||
return nil
|
||||
}
|
||||
|
||||
func registDockerRunner(ctx context.Context, token string) error {
|
||||
log.Info("开始注册Runner...")
|
||||
cli, err := docker_module.CreateDockerClient(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cli.Close()
|
||||
//拉取act_runner镜像
|
||||
dockerHost, err := docker_module.GetDockerSocketPath()
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取docker socket路径失败:%v", err)
|
||||
}
|
||||
// 拉取镜像
|
||||
err = docker_module.PullImage(cli, dockerHost, setting.Runner.Image)
|
||||
if err != nil {
|
||||
return fmt.Errorf("拉取act_runner镜像失败:%v", err)
|
||||
}
|
||||
//获取本机IP
|
||||
ips, err := getLocalIP()
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取本机IP失败:%v", err)
|
||||
}
|
||||
//获取InstanceUrl
|
||||
conntype := strings.Split(setting.AppURL, "://")[0]
|
||||
port := setting.HTTPPort
|
||||
instanceURL := conntype + "://" + ips[0] + ":" + port
|
||||
timestamp := time.Now().Format("20060102150405")
|
||||
//Runner配置
|
||||
env := []string{
|
||||
"GITEA_INSTANCE_URL=" + instanceURL,
|
||||
"GITEA_RUNNER_REGISTRATION_TOKEN=" + token,
|
||||
"GITEA_RUNNER_NAME=runner-" + timestamp,
|
||||
}
|
||||
binds := []string{
|
||||
"/var/run/docker.sock:/var/run/docker.sock",
|
||||
}
|
||||
containerName := "runner-" + timestamp
|
||||
//创建并启动Runner容器
|
||||
err = docker_module.CreateAndStartContainer(cli, setting.Runner.Image, nil, env, binds, nil, containerName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("创建并注册Runner失败:%v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func DeleteRunnerByName(ctx context.Context, runnerName string) error {
|
||||
log.Info("开始停止并删除容器: %s", runnerName)
|
||||
var err error
|
||||
if checkK8sIsEnable() {
|
||||
err = deleteK8sRunnerByName(ctx, runnerName)
|
||||
} else {
|
||||
err = deleteDockerRunnerByName(ctx, runnerName)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("删除Runner失败:%v", err)
|
||||
}
|
||||
log.Info("Runner删除成功: %s", runnerName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteDockerRunnerByName(ctx context.Context, runnerName string) error {
|
||||
log.Info("开始停止并删除容器: %s", runnerName)
|
||||
|
||||
// 创建Docker客户端
|
||||
cli, err := docker_module.CreateDockerClient(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Docker client创建失败:%v", err)
|
||||
}
|
||||
log.Info("[StopAndRemoveContainer]Docker client创建成功")
|
||||
defer cli.Close()
|
||||
err = docker_module.DeleteContainer(cli, runnerName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Runner创建失败:%v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getLocalIP() ([]string, error) {
|
||||
var ips []string
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, iface := range interfaces {
|
||||
if iface.Flags&net.FlagUp == 0 ||
|
||||
iface.Flags&net.FlagLoopback != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// 遍历地址列表
|
||||
for _, addr := range addrs {
|
||||
var ip net.IP
|
||||
switch v := addr.(type) {
|
||||
case *net.IPNet:
|
||||
ip = v.IP
|
||||
case *net.IPAddr:
|
||||
ip = v.IP
|
||||
}
|
||||
if ip == nil || ip.IsLoopback() {
|
||||
continue
|
||||
}
|
||||
|
||||
ip = ip.To4()
|
||||
if ip == nil {
|
||||
continue // 非IPv4地址
|
||||
}
|
||||
|
||||
ips = append(ips, ip.String())
|
||||
}
|
||||
}
|
||||
if len(ips) == 0 {
|
||||
return nil, fmt.Errorf("no valid IP address found")
|
||||
}
|
||||
return ips, nil
|
||||
}
|
||||
|
||||
func getK8sUrlAndToken() (string, string, error) {
|
||||
if !checkK8sIsEnable() {
|
||||
return "", "", fmt.Errorf("K8s未启用")
|
||||
}
|
||||
k8sUrl := setting.K8sConfig.Url
|
||||
k8sToken := setting.K8sConfig.Token
|
||||
|
||||
if k8sUrl == "" || k8sToken == "" {
|
||||
return "", "", fmt.Errorf("K8s配置不完整")
|
||||
}
|
||||
return k8sUrl, k8sToken, nil
|
||||
}
|
||||
|
||||
func registK8sRunner(ctx context.Context, token string) error {
|
||||
log.Info("开始注册Kubernetes Runner: %s", token)
|
||||
k8sURL, k8sToken, err := getK8sUrlAndToken()
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取K8s配置失败: %v", err)
|
||||
}
|
||||
|
||||
// 测试连接
|
||||
err = testKubernetesConnection(k8sURL, k8sToken)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Kubernetes连接测试失败: %v", err)
|
||||
}
|
||||
|
||||
// 创建K8s客户端
|
||||
clientset, err := createKubernetesClient(k8sURL, k8sToken)
|
||||
if err != nil {
|
||||
return fmt.Errorf("创建Kubernetes客户端失败: %v", err)
|
||||
}
|
||||
// 获取实例URL
|
||||
instanceURL, err := getInstanceURL()
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取实例URL失败: %v", err)
|
||||
}
|
||||
|
||||
// 创建Runner Deployment
|
||||
deployment, err := createRunnerDeployment(token, instanceURL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("创建Runner Deployment配置失败: %v", err)
|
||||
}
|
||||
|
||||
// 部署到Kubernetes
|
||||
//namespace := setting.K8sConfig.Namespace
|
||||
var namespace string
|
||||
if namespace == "" {
|
||||
namespace = "act-runner"
|
||||
}
|
||||
|
||||
_, err = clientset.AppsV1().Deployments(namespace).Create(ctx, deployment, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("在Kubernetes中创建Runner Deployment失败: %v", err)
|
||||
}
|
||||
|
||||
log.Info("成功在Kubernetes中创建Runner: %s", deployment.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func getInstanceURL() (string, error) {
|
||||
// 如果AppURL是公网地址,直接使用
|
||||
if setting.AppURL != "" &&
|
||||
!strings.Contains(setting.AppURL, "127.0.0.1") &&
|
||||
!strings.Contains(setting.AppURL, "localhost") {
|
||||
log.Info("使用配置的AppURL: %s", setting.AppURL)
|
||||
return setting.AppURL, nil
|
||||
}
|
||||
|
||||
// 否则构建URL
|
||||
ips, err := getLocalIP()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("获取本机IP失败: %v", err)
|
||||
}
|
||||
|
||||
if len(ips) == 0 {
|
||||
return "", fmt.Errorf("没有找到有效的IP地址")
|
||||
}
|
||||
|
||||
// 使用第一个IP构建URL
|
||||
conntype := "http"
|
||||
if strings.Contains(setting.AppURL, "https://") {
|
||||
conntype = "https"
|
||||
}
|
||||
|
||||
port := setting.HTTPPort
|
||||
instanceURL := conntype + "://" + ips[0] + ":" + port
|
||||
|
||||
log.Info("构建的实例URL: %s", instanceURL)
|
||||
return instanceURL, nil
|
||||
}
|
||||
func deleteK8sRunnerByName(ctx context.Context, runnerName string) error {
|
||||
log.Info("开始删除K8s Runner: %s", runnerName)
|
||||
|
||||
// 创建Kubernetes客户端
|
||||
clientset, err := createKubernetesClient(setting.K8sConfig.Url, setting.K8sConfig.Token)
|
||||
if err != nil {
|
||||
return fmt.Errorf("创建Kubernetes客户端失败: %v", err)
|
||||
}
|
||||
|
||||
// 设置namespace,与创建时保持一致
|
||||
|
||||
namespace := "act-runner"
|
||||
|
||||
// 删除Deployment
|
||||
err = clientset.AppsV1().Deployments(namespace).Delete(ctx, runnerName, metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("删除K8s Runner Deployment失败: %v", err)
|
||||
}
|
||||
|
||||
log.Info("成功删除K8s Runner Deployment: %s", runnerName)
|
||||
return nil
|
||||
}
|
||||
func createKubernetesClient(k8sURL, token string) (*kubernetes.Clientset, error) {
|
||||
config := &rest.Config{
|
||||
Host: k8sURL,
|
||||
BearerToken: token,
|
||||
TLSClientConfig: rest.TLSClientConfig{
|
||||
Insecure: true,
|
||||
},
|
||||
}
|
||||
|
||||
// 创建客户端
|
||||
clientset, err := kubernetes.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("创建Kubernetes客户端失败: %v", err)
|
||||
}
|
||||
|
||||
return clientset, nil
|
||||
}
|
||||
func testKubernetesConnection(k8sURL, token string) error {
|
||||
clientset, err := createKubernetesClient(k8sURL, token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 尝试获取节点列表来测试连接
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
_, err = clientset.CoreV1().Nodes().List(ctx, metav1.ListOptions{Limit: 1})
|
||||
if err != nil {
|
||||
return fmt.Errorf("无法连接到Kubernetes集群: %v", err)
|
||||
}
|
||||
|
||||
log.Info("Kubernetes连接测试成功")
|
||||
return nil
|
||||
}
|
||||
|
||||
func createRunnerDeployment(token, instanceURL string) (*appsv1.Deployment, error) {
|
||||
timestamp := time.Now().Format("20060102150405")
|
||||
name := "act-runner-" + timestamp
|
||||
|
||||
labels := map[string]string{
|
||||
"app": "act-runner",
|
||||
"type": "runner",
|
||||
"version": "1.0",
|
||||
}
|
||||
|
||||
// 副本数从配置获取
|
||||
replicas := int32(1)
|
||||
|
||||
// 创建Deployment配置
|
||||
deployment := &appsv1.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Labels: labels,
|
||||
},
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: &replicas,
|
||||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
"app": "act-runner",
|
||||
},
|
||||
},
|
||||
Template: corev1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"app": "act-runner",
|
||||
},
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
Containers: []corev1.Container{
|
||||
{
|
||||
Name: "act-runner", // 匹配现有配置中的容器名
|
||||
Image: setting.Runner.Image,
|
||||
Ports: []corev1.ContainerPort{
|
||||
{
|
||||
Name: "http-0",
|
||||
ContainerPort: 3000,
|
||||
Protocol: corev1.ProtocolTCP,
|
||||
},
|
||||
},
|
||||
Env: []corev1.EnvVar{
|
||||
{
|
||||
Name: "GITEA_INSTANCE_URL",
|
||||
Value: instanceURL,
|
||||
},
|
||||
{
|
||||
Name: "GITEA_RUNNER_REGISTRATION_TOKEN",
|
||||
Value: token,
|
||||
},
|
||||
{
|
||||
Name: "GITEA_RUNNER_NAME", // 可选:如果需要设置runner名称
|
||||
Value: name,
|
||||
},
|
||||
},
|
||||
// 移除资源限制以匹配现有配置(现有配置中 resources: {})
|
||||
Resources: corev1.ResourceRequirements{},
|
||||
// 挂载Docker socket
|
||||
VolumeMounts: []corev1.VolumeMount{
|
||||
{
|
||||
Name: "docker-sock",
|
||||
MountPath: "/var/run/docker.sock",
|
||||
},
|
||||
},
|
||||
ImagePullPolicy: corev1.PullIfNotPresent,
|
||||
},
|
||||
},
|
||||
// Docker socket卷
|
||||
Volumes: []corev1.Volume{
|
||||
{
|
||||
Name: "docker-sock",
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
HostPath: &corev1.HostPathVolumeSource{
|
||||
Path: "/var/run/docker.sock",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RestartPolicy: corev1.RestartPolicyAlways,
|
||||
ServiceAccountName: "default", // 匹配现有配置
|
||||
DNSPolicy: corev1.DNSClusterFirst,
|
||||
// 添加节点选择器(如果需要)
|
||||
NodeSelector: map[string]string{
|
||||
"kubernetes.io/hostname": "node1", // 可以从配置中读取
|
||||
},
|
||||
// 添加容忍度
|
||||
Tolerations: []corev1.Toleration{
|
||||
{
|
||||
Key: "node.kubernetes.io/not-ready",
|
||||
Operator: corev1.TolerationOpExists,
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TolerationSeconds: func() *int64 { i := int64(300); return &i }(),
|
||||
},
|
||||
{
|
||||
Key: "node.kubernetes.io/unreachable",
|
||||
Operator: corev1.TolerationOpExists,
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TolerationSeconds: func() *int64 { i := int64(300); return &i }(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return deployment, nil
|
||||
}
|
||||
@@ -158,6 +158,27 @@
|
||||
<!-- Optional Settings -->
|
||||
<h4 class="ui dividing header">{{ctx.Locale.Tr "install.optional_title"}}</h4>
|
||||
<div>
|
||||
<!-- k8s -->
|
||||
<details class="optional field">
|
||||
<summary class="right-content tw-py-2{{if .Err_SMTP}} text red{{end}}">
|
||||
{{ctx.Locale.Tr "install.k8s_title"}}
|
||||
</summary>
|
||||
<div class="inline field">
|
||||
<div class="ui checkbox" id="enable-k8s">
|
||||
<label data-tooltip-content="{{ctx.Locale.Tr "install.k8s_enable"}}">{{ctx.Locale.Tr "install.k8s_enable"}}</label>
|
||||
<input name="k8s_enable" type="checkbox" {{if .k8s_enable}}checked{{end}}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inline field">
|
||||
<label for="k8s_url">{{ctx.Locale.Tr "install.k8s_url"}}</label>
|
||||
<input id="k8s_url" name="k8s_url" value="{{.k8s_url}}">
|
||||
</div>
|
||||
<div class="inline field">
|
||||
<label for="k8s_token">{{ctx.Locale.Tr "install.k8s_token"}}</label>
|
||||
<input id="k8s_token" name="k8s_token" value="{{.k8s_token}}">
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
<!-- Email -->
|
||||
<details class="optional field">
|
||||
<summary class="right-content tw-py-2{{if .Err_SMTP}} text red{{end}}">
|
||||
|
||||
@@ -36,6 +36,11 @@
|
||||
<input id="description" name="description" value="{{.Runner.Description}}">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="agentlabels">{{ctx.Locale.Tr "actions.runners.labels"}}</label>
|
||||
<input id="agentlabels" name="agentlabels" value="{{range $i, $label := .Runner.AgentLabels}}{{if $i}}, {{end}}{{$label}}{{end}}">
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="field">
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
</button>
|
||||
<div class="menu">
|
||||
<div class="item">
|
||||
<a href="{{$.Link}}/regist_runner">{{ctx.Locale.Tr "actions.runners.regist_runner"}}</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
<a href="https://docs.gitea.com/usage/actions/act-runner">{{ctx.Locale.Tr "actions.runners.new_notice"}}</a>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user