Compare commits
3 Commits
2f0b9af67c
...
80219a3d0a
| Author | SHA1 | Date | |
|---|---|---|---|
|
80219a3d0a
|
|||
|
e8caa6a23d
|
|||
|
3c31105fc6
|
@@ -1,15 +1,3 @@
|
|||||||
kind: PersistentVolumeClaim
|
|
||||||
apiVersion: v1
|
|
||||||
metadata:
|
|
||||||
name: action-runner
|
|
||||||
namespace: homelab
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteMany
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 10Gi
|
|
||||||
storageClassName: longhorn
|
|
||||||
---
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
export { GiteaServer } from "./server";
|
export { GiteaServer } from "./server";
|
||||||
|
export { GiteaRunner } from "./runner";
|
||||||
|
|||||||
144
utility-services/gitea/runner.ts
Normal file
144
utility-services/gitea/runner.ts
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
import { Construct } from "constructs";
|
||||||
|
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
|
||||||
|
|
||||||
|
import { OnePasswordSecret, LonghornPvc } from "../../utils";
|
||||||
|
import { DeploymentV1 } from "@cdktf/provider-kubernetes/lib/deployment-v1";
|
||||||
|
import { PodDisruptionBudgetV1 } from "@cdktf/provider-kubernetes/lib/pod-disruption-budget-v1";
|
||||||
|
|
||||||
|
type GiteaRunnerOptions = {
|
||||||
|
provider: KubernetesProvider;
|
||||||
|
name: string;
|
||||||
|
namespace: string;
|
||||||
|
replicas?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export class GiteaRunner extends Construct {
|
||||||
|
constructor(scope: Construct, id: string, options: GiteaRunnerOptions) {
|
||||||
|
super(scope, id);
|
||||||
|
|
||||||
|
const { provider, name, namespace } = options;
|
||||||
|
const replicas = options.replicas?.toString() ?? "1";
|
||||||
|
|
||||||
|
const pvc = new LonghornPvc(this, "data-pvc", {
|
||||||
|
provider,
|
||||||
|
name: `${name}-data`,
|
||||||
|
namespace: namespace,
|
||||||
|
size: "10Gi",
|
||||||
|
accessModes: ["ReadWriteMany"],
|
||||||
|
});
|
||||||
|
|
||||||
|
new OnePasswordSecret(this, "runner-secret", {
|
||||||
|
provider,
|
||||||
|
name: "runner-secret",
|
||||||
|
namespace: namespace,
|
||||||
|
itemPath: "vaults/Lab/items/Gitea",
|
||||||
|
});
|
||||||
|
|
||||||
|
new PodDisruptionBudgetV1(this, "pdb", {
|
||||||
|
provider,
|
||||||
|
metadata: {
|
||||||
|
name,
|
||||||
|
namespace,
|
||||||
|
},
|
||||||
|
spec: {
|
||||||
|
minAvailable: replicas,
|
||||||
|
selector: {
|
||||||
|
matchLabels: {
|
||||||
|
app: name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
new DeploymentV1(this, "gitea-runner", {
|
||||||
|
provider,
|
||||||
|
metadata: {
|
||||||
|
name: name,
|
||||||
|
namespace: namespace,
|
||||||
|
labels: {
|
||||||
|
app: name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
spec: {
|
||||||
|
replicas,
|
||||||
|
selector: {
|
||||||
|
matchLabels: {
|
||||||
|
app: name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
template: {
|
||||||
|
metadata: {
|
||||||
|
labels: {
|
||||||
|
app: name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
spec: {
|
||||||
|
nodeSelector: {
|
||||||
|
nodepool: "worker",
|
||||||
|
},
|
||||||
|
topologySpreadConstraint: [
|
||||||
|
{
|
||||||
|
maxSkew: 1,
|
||||||
|
topologyKey: "kubernetes.io/hostname",
|
||||||
|
whenUnsatisfiable: "DoNotSchedule",
|
||||||
|
labelSelector: [
|
||||||
|
{
|
||||||
|
matchLabels: {
|
||||||
|
app: name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
restartPolicy: "Always",
|
||||||
|
securityContext: {
|
||||||
|
fsGroup: "1000",
|
||||||
|
},
|
||||||
|
container: [
|
||||||
|
{
|
||||||
|
name: "gitea-runner",
|
||||||
|
image: "gitea/act_runner:nightly-dind-rootless",
|
||||||
|
env: [
|
||||||
|
{
|
||||||
|
name: "DOCKER_HOST",
|
||||||
|
value: "unix:///run/user/1000/docker.sock",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GITEA_INSTANCE_URL",
|
||||||
|
value: "https://git.dogar.dev",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GITEA_RUNNER_REGISTRATION_TOKEN",
|
||||||
|
valueFrom: {
|
||||||
|
secretKeyRef: {
|
||||||
|
name: "runner-secret",
|
||||||
|
key: "runner-token",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
securityContext: {
|
||||||
|
privileged: true,
|
||||||
|
},
|
||||||
|
volumeMount: [
|
||||||
|
{
|
||||||
|
name: "runner-data",
|
||||||
|
mountPath: "/data",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
volume: [
|
||||||
|
{
|
||||||
|
name: "runner-data",
|
||||||
|
persistentVolumeClaim: {
|
||||||
|
claimName: pvc.name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,13 @@
|
|||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
import { HelmProvider } from "@cdktf/provider-helm/lib/provider";
|
|
||||||
import { Release } from "@cdktf/provider-helm/lib/release";
|
import { Release } from "@cdktf/provider-helm/lib/release";
|
||||||
import { Construct } from "constructs";
|
import { Construct } from "constructs";
|
||||||
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
|
|
||||||
|
|
||||||
import { OnePasswordSecret } from "../../utils";
|
import { OnePasswordSecret, IngressRoute, IngressRouteTcp } from "../../utils";
|
||||||
import { IngressRoute, IngressRouteTcp } from "../../utils/traefik";
|
import type { Providers } from "../../types";
|
||||||
|
|
||||||
type GiteaServerOptions = {
|
type GiteaServerOptions = {
|
||||||
providers: {
|
providers: Providers;
|
||||||
helm: HelmProvider;
|
|
||||||
kubernetes: KubernetesProvider;
|
|
||||||
};
|
|
||||||
name: string;
|
name: string;
|
||||||
namespace: string;
|
namespace: string;
|
||||||
r2Endpoint: string;
|
r2Endpoint: string;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { DataTerraformRemoteStateS3, TerraformStack } from "cdktf";
|
|||||||
import { Construct } from "constructs";
|
import { Construct } from "constructs";
|
||||||
|
|
||||||
import { ValkeyCluster } from "./valkey";
|
import { ValkeyCluster } from "./valkey";
|
||||||
import { GiteaServer } from "./gitea";
|
import { GiteaRunner, GiteaServer } from "./gitea";
|
||||||
import { AuthentikServer } from "./authentik";
|
import { AuthentikServer } from "./authentik";
|
||||||
import { PostgresCluster } from "./postgres";
|
import { PostgresCluster } from "./postgres";
|
||||||
import { DynamicDNS } from "./dynamic-dns";
|
import { DynamicDNS } from "./dynamic-dns";
|
||||||
@@ -110,5 +110,12 @@ export class UtilityServices extends TerraformStack {
|
|||||||
});
|
});
|
||||||
|
|
||||||
gitea.node.addDependency(authentik);
|
gitea.node.addDependency(authentik);
|
||||||
|
|
||||||
|
new GiteaRunner(this, "gitea-runner", {
|
||||||
|
provider: kubernetes,
|
||||||
|
namespace,
|
||||||
|
name: "gitea-runner",
|
||||||
|
replicas: 3,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Construct } from "constructs";
|
|||||||
import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest";
|
import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest";
|
||||||
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
|
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
|
||||||
|
|
||||||
export interface CertificateOptions {
|
type CertificateOptions = {
|
||||||
provider: KubernetesProvider;
|
provider: KubernetesProvider;
|
||||||
|
|
||||||
/** Namespace to create the Certificate in */
|
/** Namespace to create the Certificate in */
|
||||||
@@ -28,7 +28,7 @@ export interface CertificateOptions {
|
|||||||
|
|
||||||
/** Optional renewBefore (default: cert-manager default) */
|
/** Optional renewBefore (default: cert-manager default) */
|
||||||
renewBefore?: string;
|
renewBefore?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
class Certificate extends Construct {
|
class Certificate extends Construct {
|
||||||
public readonly manifest: Manifest;
|
public readonly manifest: Manifest;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export { CloudflareCertificate } from "./cert-manager";
|
export { CloudflareCertificate } from "./cert-manager";
|
||||||
export { OnePasswordSecret } from "./1password-secret";
|
export { OnePasswordSecret } from "./1password-secret";
|
||||||
export { IngressRoute } from "./traefik";
|
export { IngressRoute, IngressRouteTcp } from "./traefik";
|
||||||
|
export { LonghornPvc } from "./longhorn";
|
||||||
|
|||||||
59
utils/longhorn/index.ts
Normal file
59
utils/longhorn/index.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { Construct } from "constructs";
|
||||||
|
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
|
||||||
|
import { PersistentVolumeClaimV1 } from "@cdktf/provider-kubernetes/lib/persistent-volume-claim-v1";
|
||||||
|
|
||||||
|
type LonghornPvcOptions = {
|
||||||
|
provider: KubernetesProvider;
|
||||||
|
|
||||||
|
/** Name of the PVC */
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
/** Namespace of the PVC */
|
||||||
|
namespace: string;
|
||||||
|
|
||||||
|
/** Size, e.g. "10Gi" */
|
||||||
|
size: string;
|
||||||
|
|
||||||
|
/** Access modes (default: ["ReadWriteOnce"]) */
|
||||||
|
accessModes?: string[];
|
||||||
|
|
||||||
|
/** Optional PVC labels */
|
||||||
|
labels?: Record<string, string>;
|
||||||
|
|
||||||
|
/** Add backup annotations */
|
||||||
|
backup?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export class LonghornPvc extends Construct {
|
||||||
|
public readonly name: string;
|
||||||
|
|
||||||
|
constructor(scope: Construct, id: string, opts: LonghornPvcOptions) {
|
||||||
|
super(scope, id);
|
||||||
|
|
||||||
|
this.name = opts.name;
|
||||||
|
|
||||||
|
new PersistentVolumeClaimV1(this, id, {
|
||||||
|
provider: opts.provider,
|
||||||
|
metadata: {
|
||||||
|
name: opts.name,
|
||||||
|
namespace: opts.namespace,
|
||||||
|
labels: opts.labels ?? {},
|
||||||
|
annotations: opts.backup
|
||||||
|
? {
|
||||||
|
"recurring-job.longhorn.io/daily-backup": "enabled",
|
||||||
|
"recurring-job.longhorn.io/source": "enabled",
|
||||||
|
}
|
||||||
|
: {},
|
||||||
|
},
|
||||||
|
spec: {
|
||||||
|
accessModes: opts.accessModes ?? ["ReadWriteOnce"],
|
||||||
|
storageClassName: "longhorn", // HARD-CODED
|
||||||
|
resources: {
|
||||||
|
requests: {
|
||||||
|
storage: opts.size,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ import { Construct } from "constructs";
|
|||||||
import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest";
|
import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest";
|
||||||
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
|
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
|
||||||
|
|
||||||
export interface IngressRouteTcpOptions {
|
type IngressRouteTcpOptions = {
|
||||||
provider: KubernetesProvider;
|
provider: KubernetesProvider;
|
||||||
|
|
||||||
/** Namespace where the IngressRouteTCP will be created */
|
/** Namespace where the IngressRouteTCP will be created */
|
||||||
@@ -25,7 +25,7 @@ export interface IngressRouteTcpOptions {
|
|||||||
|
|
||||||
/** Name override (CR name) */
|
/** Name override (CR name) */
|
||||||
name?: string;
|
name?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class IngressRouteTcp extends Construct {
|
export class IngressRouteTcp extends Construct {
|
||||||
public readonly manifest: Manifest;
|
public readonly manifest: Manifest;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
|
|||||||
|
|
||||||
import { CloudflareCertificate } from "../cert-manager";
|
import { CloudflareCertificate } from "../cert-manager";
|
||||||
|
|
||||||
export interface IngressRouteOptions {
|
type IngressRouteOptions = {
|
||||||
provider: KubernetesProvider;
|
provider: KubernetesProvider;
|
||||||
namespace: string;
|
namespace: string;
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ export interface IngressRouteOptions {
|
|||||||
|
|
||||||
/** Name override (otherwise auto) */
|
/** Name override (otherwise auto) */
|
||||||
name?: string;
|
name?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class IngressRoute extends Construct {
|
export class IngressRoute extends Construct {
|
||||||
public readonly manifest: Manifest;
|
public readonly manifest: Manifest;
|
||||||
|
|||||||
Reference in New Issue
Block a user