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