feat: add admin argo app, act-runner, and gitea configuration
This commit is contained in:
parent
47cf042722
commit
d7bda1aeb1
|
|
@ -0,0 +1,22 @@
|
||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: admin
|
||||||
|
namespace: argocd
|
||||||
|
finalizers:
|
||||||
|
- resources-finalizer.argocd.argoproj.io
|
||||||
|
spec:
|
||||||
|
project: default
|
||||||
|
source:
|
||||||
|
repoURL: https://bitbucket.org/jamkazam/video-iac.git
|
||||||
|
targetRevision: HEAD
|
||||||
|
path: k8s/jam-cloud
|
||||||
|
directory:
|
||||||
|
include: 'admin.yaml'
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: jam-cloud
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
prune: true
|
||||||
|
selfHeal: true
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: act-runner-config
|
||||||
|
namespace: jam-cloud-infra
|
||||||
|
data:
|
||||||
|
config.yaml: |
|
||||||
|
log:
|
||||||
|
level: info
|
||||||
|
runner:
|
||||||
|
capacity: 1
|
||||||
|
timeout: 3h
|
||||||
|
container:
|
||||||
|
network: ""
|
||||||
|
# Give the job container access to the Docker daemon so Dagger can spin up its engine
|
||||||
|
options: "-v /var/run/docker.sock:/var/run/docker.sock"
|
||||||
|
valid_volumes:
|
||||||
|
- "**"
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: act-runner
|
||||||
|
namespace: jam-cloud-infra
|
||||||
|
labels:
|
||||||
|
app: act-runner
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: act-runner
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: act-runner
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: runner
|
||||||
|
image: gitea/act_runner:latest
|
||||||
|
env:
|
||||||
|
- name: CONFIG_FILE
|
||||||
|
value: /etc/act_runner/config.yaml
|
||||||
|
- name: GITEA_INSTANCE_URL
|
||||||
|
value: http://gitea.jam-cloud-infra.svc.cluster.local:80
|
||||||
|
- name: GITEA_RUNNER_REGISTRATION_TOKEN
|
||||||
|
value: "UL6SkV1E8cN6M017vNrmN3X2PPGxmcIDjsbbUvuq"
|
||||||
|
- name: GITEA_RUNNER_NAME
|
||||||
|
value: "k8s-runner"
|
||||||
|
- name: GITEA_RUNNER_LABELS
|
||||||
|
value: "ubuntu-latest:docker://node:16-bullseye,ubuntu-22.04:docker://node:16-bullseye,dagger:docker://nixpkgs/nix:latest"
|
||||||
|
securityContext:
|
||||||
|
privileged: true
|
||||||
|
volumeMounts:
|
||||||
|
- name: docker-sock
|
||||||
|
mountPath: /var/run/docker.sock
|
||||||
|
- name: config
|
||||||
|
mountPath: /etc/act_runner
|
||||||
|
- name: dind
|
||||||
|
image: docker:23.0.5-dind
|
||||||
|
env:
|
||||||
|
- name: DOCKER_TLS_CERTDIR
|
||||||
|
value: ""
|
||||||
|
securityContext:
|
||||||
|
privileged: true
|
||||||
|
volumeMounts:
|
||||||
|
- name: docker-sock
|
||||||
|
mountPath: /var/run/docker.sock
|
||||||
|
volumes:
|
||||||
|
- name: docker-sock
|
||||||
|
emptyDir: {}
|
||||||
|
- name: config
|
||||||
|
configMap:
|
||||||
|
name: act-runner-config
|
||||||
|
|
@ -0,0 +1,194 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: gitea-data
|
||||||
|
namespace: jam-cloud-infra
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
|
storageClassName: linode-block-storage-retain
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: gitea-config
|
||||||
|
namespace: jam-cloud-infra
|
||||||
|
data:
|
||||||
|
app.ini: |
|
||||||
|
APP_NAME = Gitea: Git with a cup of tea
|
||||||
|
RUN_MODE = prod
|
||||||
|
WORK_PATH = /data/gitea
|
||||||
|
|
||||||
|
[repository]
|
||||||
|
ROOT = /data/git/repositories
|
||||||
|
ALLOWED_SCHEMES = http,https,ssh,git
|
||||||
|
|
||||||
|
[repository.local]
|
||||||
|
LOCAL_COPY_PATH = /data/gitea/tmp/local-repo
|
||||||
|
|
||||||
|
[repository.upload]
|
||||||
|
TEMP_PATH = /data/gitea/uploads
|
||||||
|
|
||||||
|
[server]
|
||||||
|
APP_DATA_PATH = /data/gitea
|
||||||
|
DOMAIN = git.staging.jamkazam.com
|
||||||
|
SSH_DOMAIN = localhost
|
||||||
|
HTTP_PORT = 3000
|
||||||
|
ROOT_URL = https://git.staging.jamkazam.com/
|
||||||
|
DISABLE_SSH = false
|
||||||
|
SSH_PORT = 22
|
||||||
|
SSH_LISTEN_PORT = 22
|
||||||
|
LFS_START_SERVER = false
|
||||||
|
|
||||||
|
[database]
|
||||||
|
PATH = /data/gitea/gitea.db
|
||||||
|
DB_TYPE = sqlite3
|
||||||
|
HOST = localhost:3306
|
||||||
|
NAME = gitea
|
||||||
|
USER = root
|
||||||
|
PASSWD =
|
||||||
|
LOG_SQL = false
|
||||||
|
|
||||||
|
[indexer]
|
||||||
|
ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve
|
||||||
|
|
||||||
|
[session]
|
||||||
|
PROVIDER_CONFIG = /data/gitea/sessions
|
||||||
|
|
||||||
|
[picture]
|
||||||
|
AVATAR_UPLOAD_PATH = /data/gitea/avatars
|
||||||
|
REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars
|
||||||
|
|
||||||
|
[attachment]
|
||||||
|
PATH = /data/gitea/attachments
|
||||||
|
|
||||||
|
[log]
|
||||||
|
MODE = console
|
||||||
|
LEVEL = info
|
||||||
|
ROOT_PATH = /data/gitea/log
|
||||||
|
|
||||||
|
[security]
|
||||||
|
INSTALL_LOCK = true
|
||||||
|
SECRET_KEY =
|
||||||
|
REVERSE_PROXY_LIMIT = 1
|
||||||
|
REVERSE_PROXY_TRUSTED_PROXIES = *
|
||||||
|
INTERNAL_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE3NzMwMDMyODN9.c3kDP5f7-lo3yR-Z8mPiaAsSEsohWc-LxZksIqTcPWw
|
||||||
|
|
||||||
|
[service]
|
||||||
|
DISABLE_REGISTRATION = false
|
||||||
|
REQUIRE_SIGNIN_VIEW = false
|
||||||
|
|
||||||
|
[lfs]
|
||||||
|
PATH = /data/git/lfs
|
||||||
|
|
||||||
|
[openid]
|
||||||
|
ENABLE_OPENID_SIGNIN = true
|
||||||
|
ENABLE_OPENID_SIGNUP = true
|
||||||
|
|
||||||
|
[oauth2]
|
||||||
|
ENABLE = true
|
||||||
|
JWT_SECRET = HDi5Td6dRBC240L6ryMI4eMnowcwQVpfKrmIPNrEeAI
|
||||||
|
|
||||||
|
[actions]
|
||||||
|
ENABLED = true
|
||||||
|
|
||||||
|
[migrations]
|
||||||
|
ALLOW_SSH_MIGRATIONS = true
|
||||||
|
ALLOWED_DOMAINS = *
|
||||||
|
ALLOW_LOCALNETWORKS = true
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: gitea
|
||||||
|
namespace: jam-cloud-infra
|
||||||
|
labels:
|
||||||
|
app: gitea
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: gitea
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: gitea
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: gitea
|
||||||
|
image: gitea/gitea:1.21.7
|
||||||
|
ports:
|
||||||
|
- containerPort: 3000
|
||||||
|
name: http
|
||||||
|
- containerPort: 22
|
||||||
|
name: ssh
|
||||||
|
env:
|
||||||
|
- name: GITEA_CUSTOM
|
||||||
|
value: /etc/gitea
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /data
|
||||||
|
- name: config
|
||||||
|
mountPath: /etc/gitea/conf/
|
||||||
|
lifecycle:
|
||||||
|
postStart:
|
||||||
|
exec:
|
||||||
|
command: ["/bin/sh", "-c", "sleep 5; /sbin/su-exec git gitea admin user create --admin --username seth --password changeme123 --email seth@jamkazam.com --must-change-password=false || true"]
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: gitea-data
|
||||||
|
- name: config
|
||||||
|
configMap:
|
||||||
|
name: gitea-config
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: gitea
|
||||||
|
namespace: jam-cloud-infra
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: gitea
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: 3000
|
||||||
|
name: http
|
||||||
|
- port: 22
|
||||||
|
targetPort: 22
|
||||||
|
name: ssh
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: gitea
|
||||||
|
namespace: jam-cloud-infra
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt-nginx-production
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size: "512m"
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx
|
||||||
|
tls:
|
||||||
|
- secretName: gitea-tls
|
||||||
|
hosts:
|
||||||
|
- git.staging.jamkazam.com
|
||||||
|
- idp.staging.jamkazam.com
|
||||||
|
- console.staging.jamkazam.com
|
||||||
|
rules:
|
||||||
|
- host: git.staging.jamkazam.com
|
||||||
|
http: &gitea_path
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: gitea
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
- host: idp.staging.jamkazam.com
|
||||||
|
http: *gitea_path
|
||||||
|
- host: console.staging.jamkazam.com
|
||||||
|
http: *gitea_path
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: jam-cloud
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: admin
|
||||||
|
namespace: jam-cloud
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: admin
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: admin
|
||||||
|
spec:
|
||||||
|
imagePullSecrets:
|
||||||
|
- name: gitea-registry
|
||||||
|
containers:
|
||||||
|
- name: web
|
||||||
|
# This will be replaced by the Dagger build pipeline on first run
|
||||||
|
image: git.staging.jamkazam.com/seth/jam-cloud-admin:latest
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
|
env:
|
||||||
|
- name: DATABASE_URL
|
||||||
|
value: "postgres://jam:jam@72.14.176.182:5432/jam"
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: admin
|
||||||
|
namespace: jam-cloud
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: admin
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 8080
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: admin
|
||||||
|
namespace: jam-cloud
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt-nginx-production
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx
|
||||||
|
tls:
|
||||||
|
- secretName: admin-tls
|
||||||
|
hosts:
|
||||||
|
- admin.staging.jamkazam.com
|
||||||
|
rules:
|
||||||
|
- host: admin.staging.jamkazam.com
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: admin
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
repositories:
|
||||||
|
- name: "jam-cloud"
|
||||||
|
url: "https://bitbucket.org/jamkazam/jam-cloud.git"
|
||||||
|
- name: "video-iac"
|
||||||
|
url: "https://bitbucket.org/jamkazam/video-iac.git"
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
require 'net/http'
|
||||||
|
require 'json'
|
||||||
|
require 'uri'
|
||||||
|
require 'yaml'
|
||||||
|
require 'optparse'
|
||||||
|
|
||||||
|
# Configuration mapping
|
||||||
|
ENV_CONFIG = {
|
||||||
|
'stg' => {
|
||||||
|
url: "https://git.staging.jamkazam.com/api/v1",
|
||||||
|
token_var: "GITEA_TOKEN_STG"
|
||||||
|
},
|
||||||
|
'prd' => {
|
||||||
|
url: "https://git.jamkazam.com/api/v1",
|
||||||
|
token_var: "GITEA_TOKEN_PRD"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
options = { env: 'stg' }
|
||||||
|
OptionParser.new do |opts|
|
||||||
|
opts.banner = "Usage: ruby sync-gitea-repos.rb [options] <bitbucket_user> <bitbucket_pass>"
|
||||||
|
opts.on("-e", "--env ENV", "Environment (stg or prd, default stg)") { |v| options[:env] = v }
|
||||||
|
end.parse!
|
||||||
|
|
||||||
|
if ARGV.length < 2
|
||||||
|
puts "❌ Error: Missing Bitbucket credentials."
|
||||||
|
puts "Usage: ruby sync-gitea-repos.rb --env [stg|prd] <bb_user> <bb_pass>"
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
|
BB_USER = ARGV[0]
|
||||||
|
BB_PASS = ARGV[1]
|
||||||
|
|
||||||
|
# Select config
|
||||||
|
config = ENV_CONFIG[options[:env]]
|
||||||
|
if config.nil?
|
||||||
|
puts "❌ Error: Invalid environment '#{options[:env]}'. Use 'stg' or 'prd'."
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
|
# Resolve Token
|
||||||
|
GITEA_TOKEN = ENV[config[:token_var]] || ENV['GITEA_TOKEN']
|
||||||
|
GITEA_URL = config[:url]
|
||||||
|
GITEA_OWNER = "seth"
|
||||||
|
MANIFEST_FILE = File.expand_path('gitea-repos.yaml', __dir__)
|
||||||
|
|
||||||
|
if GITEA_TOKEN.nil? || GITEA_TOKEN.empty?
|
||||||
|
puts "❌ Error: API Token environment variable '#{config[:token_var]}' is not set."
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
|
def gitea_request(method, path, payload = nil)
|
||||||
|
uri = URI.parse("#{GITEA_URL}#{path}")
|
||||||
|
header = {
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'Authorization' => "token #{GITEA_TOKEN}"
|
||||||
|
}
|
||||||
|
http = Net::HTTP.new(uri.host, uri.port)
|
||||||
|
http.use_ssl = true
|
||||||
|
http.read_timeout = 300
|
||||||
|
|
||||||
|
case method
|
||||||
|
when :get then req = Net::HTTP::Get.new(uri.request_uri, header)
|
||||||
|
when :post then req = Net::HTTP::Post.new(uri.request_uri, header); req.body = payload.to_json if payload
|
||||||
|
when :delete then req = Net::HTTP::Delete.new(uri.request_uri, header)
|
||||||
|
end
|
||||||
|
http.request(req)
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "🚀 Reconciling Gitea mirrors for #{options[:env].upcase}..."
|
||||||
|
puts "🔗 API: #{GITEA_URL}"
|
||||||
|
|
||||||
|
# 1. Load Manifest
|
||||||
|
manifest = YAML.load_file(MANIFEST_FILE)
|
||||||
|
desired_repos = manifest['repositories']
|
||||||
|
desired_names = desired_repos.map { |r| r['name'] }
|
||||||
|
|
||||||
|
# 2. Get Current State from Gitea
|
||||||
|
puts "🔍 Fetching current repositories..."
|
||||||
|
resp = gitea_request(:get, "/users/#{GITEA_OWNER}/repos")
|
||||||
|
if resp.code != "200"
|
||||||
|
puts "❌ Failed to fetch repos: #{resp.code} #{resp.body}"
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
current_repos = JSON.parse(resp.body)
|
||||||
|
current_names = current_repos.map { |r| r['name'] }
|
||||||
|
|
||||||
|
# 3. Reconcile: Delete repos not in manifest
|
||||||
|
repos_to_delete = current_names - desired_names
|
||||||
|
repos_to_delete.each do |name|
|
||||||
|
puts "🗑️ Deleting repository '#{name}' (not in manifest)..."
|
||||||
|
gitea_request(:delete, "/repos/#{GITEA_OWNER}/#{name}")
|
||||||
|
end
|
||||||
|
|
||||||
|
# 4. Reconcile: Create/Update mirrors
|
||||||
|
desired_repos.each do |repo|
|
||||||
|
name = repo['name']
|
||||||
|
url = repo['url']
|
||||||
|
|
||||||
|
if current_names.include?(name)
|
||||||
|
repo_info = current_repos.find { |r| r['name'] == name }
|
||||||
|
if repo_info['empty']
|
||||||
|
puts "⚠️ Mirror '#{name}' exists but is EMPTY. Recreating..."
|
||||||
|
gitea_request(:delete, "/repos/#{GITEA_OWNER}/#{name}")
|
||||||
|
else
|
||||||
|
puts "✅ Mirror '#{name}' already exists. Skipping."
|
||||||
|
next
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "🚀 Creating mirror for '#{name}'..."
|
||||||
|
payload = {
|
||||||
|
"clone_addr" => url,
|
||||||
|
"auth_username" => BB_USER,
|
||||||
|
"auth_password" => BB_PASS,
|
||||||
|
"repo_name" => name,
|
||||||
|
"mirror" => true,
|
||||||
|
"mirror_interval" => "10m",
|
||||||
|
"service" => "bitbucket",
|
||||||
|
"repo_owner" => GITEA_OWNER,
|
||||||
|
"lfs" => true,
|
||||||
|
"releases" => true
|
||||||
|
}
|
||||||
|
|
||||||
|
res = gitea_request(:post, "/repos/migrate", payload)
|
||||||
|
if res.code == "201"
|
||||||
|
puts "✨ Successfully created mirror for '#{name}'."
|
||||||
|
else
|
||||||
|
puts "❌ Failed to create mirror for '#{name}': #{res.code} #{res.body}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "\n🎯 Reconcile complete for #{options[:env].upcase}."
|
||||||
Loading…
Reference in New Issue