forked from farhoodlabs/paperclip
feat(plugin): add kubernetes sandbox provider
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
export interface BuildJobManifestInput {
|
||||
namespace: string;
|
||||
jobName: string;
|
||||
adapterType: string;
|
||||
image: string;
|
||||
envSecretName: string;
|
||||
serviceAccountName: string;
|
||||
labels: Record<string, string>;
|
||||
resources: {
|
||||
requests?: { cpu?: string; memory?: string };
|
||||
limits?: { cpu?: string; memory?: string };
|
||||
};
|
||||
runtimeClassName?: string;
|
||||
activeDeadlineSec: number;
|
||||
ttlSecondsAfterFinished: number;
|
||||
imagePullSecrets?: string[];
|
||||
}
|
||||
|
||||
export function buildJobManifest(input: BuildJobManifestInput): Record<string, unknown> {
|
||||
const podLabels = {
|
||||
...input.labels,
|
||||
"paperclip.io/role": "agent",
|
||||
};
|
||||
return {
|
||||
apiVersion: "batch/v1",
|
||||
kind: "Job",
|
||||
metadata: {
|
||||
name: input.jobName,
|
||||
namespace: input.namespace,
|
||||
labels: { ...input.labels },
|
||||
},
|
||||
spec: {
|
||||
backoffLimit: 0,
|
||||
ttlSecondsAfterFinished: input.ttlSecondsAfterFinished,
|
||||
activeDeadlineSeconds: input.activeDeadlineSec,
|
||||
template: {
|
||||
metadata: { labels: podLabels },
|
||||
spec: {
|
||||
serviceAccountName: input.serviceAccountName,
|
||||
// Agent containers call back to paperclip-server via HTTPS egress;
|
||||
// they never call the Kubernetes API, so mounting an SA token is
|
||||
// unnecessary attack surface.
|
||||
automountServiceAccountToken: false,
|
||||
restartPolicy: "Never",
|
||||
...(input.runtimeClassName ? { runtimeClassName: input.runtimeClassName } : {}),
|
||||
...(input.imagePullSecrets && input.imagePullSecrets.length > 0
|
||||
? { imagePullSecrets: input.imagePullSecrets.map((name) => ({ name })) }
|
||||
: {}),
|
||||
securityContext: {
|
||||
runAsNonRoot: true,
|
||||
runAsUser: 1000,
|
||||
runAsGroup: 1000,
|
||||
fsGroup: 1000,
|
||||
fsGroupChangePolicy: "OnRootMismatch",
|
||||
seccompProfile: { type: "RuntimeDefault" },
|
||||
},
|
||||
containers: [
|
||||
{
|
||||
name: "agent",
|
||||
image: input.image,
|
||||
imagePullPolicy: "IfNotPresent",
|
||||
command: ["/usr/bin/tini", "--", "/usr/local/bin/paperclip-agent-shim"],
|
||||
envFrom: [{ secretRef: { name: input.envSecretName } }],
|
||||
securityContext: {
|
||||
runAsNonRoot: true,
|
||||
runAsUser: 1000,
|
||||
runAsGroup: 1000,
|
||||
readOnlyRootFilesystem: true,
|
||||
allowPrivilegeEscalation: false,
|
||||
capabilities: { drop: ["ALL"] },
|
||||
},
|
||||
resources: {
|
||||
requests: input.resources.requests ?? { cpu: "250m", memory: "512Mi" },
|
||||
limits: input.resources.limits ?? { cpu: "2", memory: "4Gi" },
|
||||
},
|
||||
volumeMounts: [
|
||||
{ name: "workspace", mountPath: "/workspace" },
|
||||
{ name: "home", mountPath: "/home/paperclip" },
|
||||
{ name: "cache", mountPath: "/home/paperclip/.cache" },
|
||||
{ name: "tmp", mountPath: "/tmp" },
|
||||
],
|
||||
},
|
||||
],
|
||||
volumes: [
|
||||
{ name: "workspace", emptyDir: { sizeLimit: "8Gi" } },
|
||||
{ name: "home", emptyDir: { sizeLimit: "1Gi" } },
|
||||
{ name: "cache", emptyDir: { sizeLimit: "1Gi" } },
|
||||
{ name: "tmp", emptyDir: { sizeLimit: "2Gi" } },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user