refactor: rename custom components from shannon-* to hightower-*

Renames API server, worker jobs, credentials secret, and workspaces
PVC to use the hightower prefix. Upstream Shannon names (namespace,
Temporal service, package imports, .shannon/ dir) are unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-20 09:09:34 -04:00
parent ec4b7e674f
commit 7b16bf98f7
14 changed files with 42 additions and 30 deletions
@@ -0,0 +1,3 @@
# Memory Index
- [reference_arc_runners.md](reference_arc_runners.md) — ARC self-hosted runners in farhoodliquor K8s cluster (`runners-farhoodliquor`)
@@ -0,0 +1,9 @@
---
name: ARC self-hosted runners
description: farhoodliquor org has ARC runner scale set named "runners-farhoodliquor" in their K8s cluster for GitHub Actions CI/CD
type: reference
---
The farhoodliquor GitHub org has Actions Runner Controller (ARC) deployed in their K8s cluster with a runner scale set named `runners-farhoodliquor`. The ARC configuration lives in a separate repo (not in shannon). Shannon CI workflows should target these self-hosted runners instead of GitHub-hosted runners to avoid free-tier runner minute limits.
**How to apply:** When modifying `.github/workflows/` files, use `runs-on: runners-farhoodliquor` instead of `runs-on: ubuntu-latest`.
+8 -8
View File
@@ -1,24 +1,24 @@
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: shannon-api name: hightower-api
namespace: shannon namespace: shannon
labels: labels:
app: shannon-api app: hightower-api
spec: spec:
replicas: 1 replicas: 1
selector: selector:
matchLabels: matchLabels:
app: shannon-api app: hightower-api
template: template:
metadata: metadata:
labels: labels:
app: shannon-api app: hightower-api
spec: spec:
serviceAccountName: shannon-api serviceAccountName: hightower-api
containers: containers:
- name: api - name: api
image: ghcr.io/farhoodliquor/shannon-api:latest image: ghcr.io/farhoodliquor/hightower-api:latest
ports: ports:
- containerPort: 3000 - containerPort: 3000
name: http name: http
@@ -31,7 +31,7 @@ spec:
value: shannon value: shannon
envFrom: envFrom:
- secretRef: - secretRef:
name: shannon-credentials name: hightower-credentials
volumeMounts: volumeMounts:
- name: workspaces - name: workspaces
mountPath: /app/workspaces mountPath: /app/workspaces
@@ -56,4 +56,4 @@ spec:
volumes: volumes:
- name: workspaces - name: workspaces
persistentVolumeClaim: persistentVolumeClaim:
claimName: shannon-workspaces claimName: hightower-workspaces
+4 -4
View File
@@ -1,7 +1,7 @@
apiVersion: rbac.authorization.k8s.io/v1 apiVersion: rbac.authorization.k8s.io/v1
kind: Role kind: Role
metadata: metadata:
name: shannon-api name: hightower-api
namespace: shannon namespace: shannon
rules: rules:
- apiGroups: ["batch"] - apiGroups: ["batch"]
@@ -17,13 +17,13 @@ rules:
apiVersion: rbac.authorization.k8s.io/v1 apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding kind: RoleBinding
metadata: metadata:
name: shannon-api name: hightower-api
namespace: shannon namespace: shannon
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: shannon-api name: hightower-api
namespace: shannon namespace: shannon
roleRef: roleRef:
kind: Role kind: Role
name: shannon-api name: hightower-api
apiGroup: rbac.authorization.k8s.io apiGroup: rbac.authorization.k8s.io
+2 -2
View File
@@ -1,11 +1,11 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: shannon-api name: hightower-api
namespace: shannon namespace: shannon
spec: spec:
selector: selector:
app: shannon-api app: hightower-api
ports: ports:
- name: http - name: http
port: 3000 port: 3000
+1 -1
View File
@@ -1,5 +1,5 @@
apiVersion: v1 apiVersion: v1
kind: ServiceAccount kind: ServiceAccount
metadata: metadata:
name: shannon-api name: hightower-api
namespace: shannon namespace: shannon
@@ -7,7 +7,7 @@ patches:
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: shannon-api name: hightower-api
spec: spec:
template: template:
spec: spec:
+1 -1
View File
@@ -33,6 +33,6 @@ export function loadConfig(): Config {
k8sNamespace: process.env.K8S_NAMESPACE || 'shannon', k8sNamespace: process.env.K8S_NAMESPACE || 'shannon',
workerImage, workerImage,
workspacesDir: process.env.WORKSPACES_DIR || '/app/workspaces', workspacesDir: process.env.WORKSPACES_DIR || '/app/workspaces',
credentialsSecretName: process.env.CREDENTIALS_SECRET_NAME || 'shannon-credentials', credentialsSecretName: process.env.CREDENTIALS_SECRET_NAME || 'hightower-credentials',
}; };
} }
+2 -2
View File
@@ -21,7 +21,7 @@ export interface JobParams {
readonly pipelineTesting?: boolean; readonly pipelineTesting?: boolean;
} }
const WORKER_LABEL = 'shannon-worker'; const WORKER_LABEL = 'hightower-worker';
const REPO_MOUNT_PATH = '/repo'; const REPO_MOUNT_PATH = '/repo';
export function buildJobSpec(params: JobParams): k8s.V1Job { export function buildJobSpec(params: JobParams): k8s.V1Job {
@@ -36,7 +36,7 @@ export function buildJobSpec(params: JobParams): k8s.V1Job {
// 2. Build volumes and mounts // 2. Build volumes and mounts
const volumes: k8s.V1Volume[] = [ const volumes: k8s.V1Volume[] = [
{ name: 'workspaces', persistentVolumeClaim: { claimName: 'shannon-workspaces' } }, { name: 'workspaces', persistentVolumeClaim: { claimName: 'hightower-workspaces' } },
{ name: 'shm', emptyDir: { medium: 'Memory', sizeLimit: '2Gi' } }, { name: 'shm', emptyDir: { medium: 'Memory', sizeLimit: '2Gi' } },
]; ];
+1 -1
View File
@@ -4,7 +4,7 @@
import type * as k8s from '@kubernetes/client-node'; import type * as k8s from '@kubernetes/client-node';
const WORKER_LABEL = 'shannon-worker'; const WORKER_LABEL = 'hightower-worker';
export async function createJob(batchApi: k8s.BatchV1Api, namespace: string, job: k8s.V1Job): Promise<void> { export async function createJob(batchApi: k8s.BatchV1Api, namespace: string, job: k8s.V1Job): Promise<void> {
await batchApi.createNamespacedJob({ namespace, body: job }); await batchApi.createNamespacedJob({ namespace, body: job });
+2 -2
View File
@@ -26,10 +26,10 @@ export async function startScan(
): Promise<ScanResponse> { ): Promise<ScanResponse> {
const suffix = randomSuffix(); const suffix = randomSuffix();
const taskQueue = `api-${suffix}`; const taskQueue = `api-${suffix}`;
const jobName = `shannon-worker-${suffix}`; const jobName = `hightower-worker-${suffix}`;
const workspace = const workspace =
input.workspace ?? `${new URL(input.targetUrl).hostname.replace(/[^a-zA-Z0-9-]/g, '-')}_shannon-${Date.now()}`; input.workspace ?? `${new URL(input.targetUrl).hostname.replace(/[^a-zA-Z0-9-]/g, '-')}_hightower-${Date.now()}`;
const job = buildJobSpec({ const job = buildJobSpec({
jobName, jobName,
+1 -1
View File
@@ -31,7 +31,7 @@ spec:
- containerPort: 3456 - containerPort: 3456
envFrom: envFrom:
- secretRef: - secretRef:
name: shannon-credentials name: hightower-credentials
env: env:
- name: HOST - name: HOST
value: "0.0.0.0" value: "0.0.0.0"
+1 -1
View File
@@ -1,7 +1,7 @@
apiVersion: v1 apiVersion: v1
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
metadata: metadata:
name: shannon-workspaces name: hightower-workspaces
namespace: shannon namespace: shannon
spec: spec:
accessModes: accessModes:
+6 -6
View File
@@ -20,7 +20,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
const NAMESPACE = 'shannon'; const NAMESPACE = 'shannon';
const NPX_IMAGE_REPO = 'keygraph/shannon'; const NPX_IMAGE_REPO = 'keygraph/shannon';
const DEV_IMAGE = 'shannon-worker'; const DEV_IMAGE = 'shannon-worker';
const WORKER_LABEL = 'shannon-worker'; const WORKER_LABEL = 'hightower-worker';
const K8S_MANIFESTS_DIR = path.resolve(__dirname, '..', 'infra', 'k8s'); const K8S_MANIFESTS_DIR = path.resolve(__dirname, '..', 'infra', 'k8s');
// === K8s Client Setup === // === K8s Client Setup ===
@@ -150,7 +150,7 @@ export class K8sOrchestrator implements Orchestrator {
const volumes: k8s.V1Volume[] = [ const volumes: k8s.V1Volume[] = [
{ {
name: 'workspaces', name: 'workspaces',
persistentVolumeClaim: { claimName: 'shannon-workspaces' }, persistentVolumeClaim: { claimName: 'hightower-workspaces' },
}, },
{ {
name: 'shm', name: 'shm',
@@ -230,7 +230,7 @@ export class K8sOrchestrator implements Orchestrator {
command, command,
args, args,
env, env,
envFrom: [{ secretRef: { name: 'shannon-credentials' } }], envFrom: [{ secretRef: { name: 'hightower-credentials' } }],
volumeMounts, volumeMounts,
resources: { resources: {
requests: { memory: '2Gi' }, requests: { memory: '2Gi' },
@@ -314,7 +314,7 @@ export class K8sOrchestrator implements Orchestrator {
volumeMounts.push({ name: volName, mountPath: dst }); volumeMounts.push({ name: volName, mountPath: dst });
volumes.push({ volumes.push({
name: volName, name: volName,
persistentVolumeClaim: { claimName: 'shannon-workspaces' }, persistentVolumeClaim: { claimName: 'hightower-workspaces' },
}); });
} }
} }
@@ -397,7 +397,7 @@ export class K8sOrchestrator implements Orchestrator {
apiVersion: 'v1', apiVersion: 'v1',
kind: 'Secret', kind: 'Secret',
metadata: { metadata: {
name: 'shannon-credentials', name: 'hightower-credentials',
namespace: NAMESPACE, namespace: NAMESPACE,
}, },
stringData, stringData,
@@ -405,7 +405,7 @@ export class K8sOrchestrator implements Orchestrator {
try { try {
await this.coreApi.replaceNamespacedSecret({ await this.coreApi.replaceNamespacedSecret({
name: 'shannon-credentials', name: 'hightower-credentials',
namespace: NAMESPACE, namespace: NAMESPACE,
body: secret, body: secret,
}); });