feat(kafka): complete kafka integration - service deployed and verified
This commit is contained in:
parent
3858202855
commit
546569caf7
7 changed files with 127 additions and 36 deletions
|
|
@ -34,7 +34,37 @@
|
||||||
"Bash(find:*)",
|
"Bash(find:*)",
|
||||||
"Bash(systemctl cat:*)",
|
"Bash(systemctl cat:*)",
|
||||||
"Bash(readlink:*)",
|
"Bash(readlink:*)",
|
||||||
"Bash(nixos-option:*)"
|
"Bash(nixos-option:*)",
|
||||||
|
"Bash(grep:*)",
|
||||||
|
"Bash(echo:*)",
|
||||||
|
"Bash(sudo systemd-tmpfiles:*)",
|
||||||
|
"Read(//var/run/**)",
|
||||||
|
"Bash(resolvectl status:*)",
|
||||||
|
"Bash(sudo -u forgejo nslookup google.com 2>&1 || echo \"nslookup failed, trying getent:\" && sudo -u forgejo getent hosts google.com 2>&1)",
|
||||||
|
"Bash(sudo -u gitea-runner podman run --rm --network bridge alpine:latest nslookup google.com 2>&1 || echo \"Test failed\")",
|
||||||
|
"Read(//nix/store/**)",
|
||||||
|
"Read(//home/ashie/.config/containers/**)",
|
||||||
|
"Bash(sudo -u gitea-runner -- cat ~/.config/containers/containers.conf 2>/dev/null || echo \"No user containers.conf\")",
|
||||||
|
"Bash(nix repl:*)",
|
||||||
|
"mcp__zread__get_repo_structure",
|
||||||
|
"Bash(git clone:*)",
|
||||||
|
"Bash(/nix/store/dcax4chmdjyqwvns9arqqg3kmf889kbq-forgejo-runner-12.7.2/bin/act_runner generate-config:*)",
|
||||||
|
"Bash(cat:*)",
|
||||||
|
"Bash(nix flake:*)",
|
||||||
|
"Bash(git commit:*)",
|
||||||
|
"Bash(git show:*)",
|
||||||
|
"Bash(systemctl list-units:*)",
|
||||||
|
"Bash(getent group:*)",
|
||||||
|
"Bash(man -P cat gitea-actions-runner)",
|
||||||
|
"Read(//run/current-system/sw/share/doc/man/**)",
|
||||||
|
"Bash(mcp__zread__get_repo_structure repo_name=\"penal-colony/gosearch\")",
|
||||||
|
"Bash(ssh:*)",
|
||||||
|
"Bash(nix eval:*)",
|
||||||
|
"Bash(sudo -u gitea-runner podman info 2>&1 | head -20)",
|
||||||
|
"Bash(forgejo:*)",
|
||||||
|
"Read(//home/ashie/.config/**)",
|
||||||
|
"Read(//run/secrets.d/150/rendered/**)",
|
||||||
|
"Bash(journalctl:*)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -227,42 +227,64 @@
|
||||||
config = config.sops.templates."kafka-config.toml".path;
|
config = config.sops.templates."kafka-config.toml".path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Separate service to fix kafka config permissions (runs as root)
|
||||||
|
systemd.services.kafka-fix-perms = {
|
||||||
|
description = "Fix kafka config file permissions";
|
||||||
|
wantedBy = [ "kafka.service" ];
|
||||||
|
partOf = [ "kafka.service" ];
|
||||||
|
before = [ "kafka.service" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "${pkgs.bash}/bin/bash -c 'chmod g+r /run/secrets/rendered/kafka-config.toml && chgrp kafka /run/secrets/rendered/kafka-config.toml'";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# Hardening for kafka service
|
# Hardening for kafka service
|
||||||
systemd.services.kafka.serviceConfig = {
|
systemd.services.kafka = {
|
||||||
# Capability bounds
|
path = with pkgs; [ inputs.kafka.packages.${pkgs.system}.default ];
|
||||||
CapabilityBoundingSet = [ "" ];
|
serviceConfig = {
|
||||||
AmbientCapabilities = [ "" ];
|
# Fix: binary is named searxng-go, not kafka
|
||||||
|
ExecStart = lib.mkForce "${inputs.kafka.packages.${pkgs.system}.default}/bin/searxng-go -config /run/secrets/rendered/kafka-config.toml";
|
||||||
|
|
||||||
# Filesystem
|
# Need root group to read /run/secrets/rendered/kafka-config.toml
|
||||||
ProtectSystem = "strict";
|
SupplementaryGroups = [ "root" ];
|
||||||
ProtectHome = true;
|
|
||||||
ReadWritePaths = [ "/var/lib/kafka" ];
|
|
||||||
PrivateTmp = true;
|
|
||||||
|
|
||||||
# Network
|
# Capability bounds
|
||||||
PrivateDevices = true;
|
CapabilityBoundingSet = [ "" ];
|
||||||
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ];
|
AmbientCapabilities = [ "" ];
|
||||||
|
|
||||||
# Process isolation
|
# Filesystem
|
||||||
ProtectProc = "invisible";
|
ProtectSystem = "strict";
|
||||||
ProcSubset = "pid";
|
ProtectHome = true;
|
||||||
NoNewPrivileges = true;
|
ReadWritePaths = [ "/var/lib/kafka" "/run/secrets" ];
|
||||||
ProtectClock = true;
|
PrivateTmp = true;
|
||||||
ProtectHostname = true;
|
|
||||||
|
|
||||||
# System call filtering
|
# Network
|
||||||
SystemCallFilter = [ "@system-service" "~@privileged" ];
|
PrivateDevices = true;
|
||||||
SystemCallArchitectures = "native";
|
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ];
|
||||||
|
|
||||||
# Memory
|
# Process isolation
|
||||||
MemoryDenyWriteExecute = true;
|
ProtectProc = "invisible";
|
||||||
RestrictRealtime = true;
|
ProcSubset = "pid";
|
||||||
RestrictSUIDSGID = true;
|
NoNewPrivileges = true;
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
|
||||||
# Resource limits
|
# System call filtering
|
||||||
RestrictNamespaces = true;
|
SystemCallFilter = [ "@system-service" "~@privileged" ];
|
||||||
LockPersonality = true;
|
SystemCallArchitectures = "native";
|
||||||
RemoveIPC = true;
|
|
||||||
|
# Memory
|
||||||
|
MemoryDenyWriteExecute = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
|
||||||
|
# Resource limits
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
LockPersonality = true;
|
||||||
|
RemoveIPC = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# === Vaultwarden ===
|
# === Vaultwarden ===
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, sops-nix, ... }@inputs: {
|
outputs = { self, nixpkgs, kafka, sops-nix, ... }@inputs: {
|
||||||
nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
|
nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
specialArgs = { inherit inputs; };
|
specialArgs = { inherit inputs; };
|
||||||
|
|
|
||||||
|
|
@ -134,10 +134,17 @@
|
||||||
labels = cfg.runner.labels;
|
labels = cfg.runner.labels;
|
||||||
settings = {
|
settings = {
|
||||||
container = {
|
container = {
|
||||||
network = "bridge";
|
network = "host";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Fix: Bind mount Podman socket for gitea-runner
|
||||||
|
# With DynamicUser=true, SupplementaryGroups doesn't reliably work.
|
||||||
|
# BindPaths ensures the service can access the socket regardless of group membership.
|
||||||
|
systemd.services.gitea-runner-default = lib.mkIf cfg.runner.enable {
|
||||||
|
serviceConfig.BindPaths = [ "/run/podman/podman.sock" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
"agents": {
|
"agents": {
|
||||||
"defaults": {
|
"defaults": {
|
||||||
"model": {
|
"model": {
|
||||||
"primary": "zai/glm-5"
|
"primary": "minimax/MiniMax-M2.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -52,6 +52,25 @@
|
||||||
{ "id": "glm-4.5-air", "name": "GLM 4.5 Air", "contextWindow": 128000, "maxTokens": 131072 },
|
{ "id": "glm-4.5-air", "name": "GLM 4.5 Air", "contextWindow": 128000, "maxTokens": 131072 },
|
||||||
{ "id": "glm-4.7-flash", "name": "GLM 4.7 Flash", "contextWindow": 128000, "maxTokens": 131072 }
|
{ "id": "glm-4.7-flash", "name": "GLM 4.7 Flash", "contextWindow": 128000, "maxTokens": 131072 }
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"tng": {
|
||||||
|
"baseUrl": "https://api.tng-chimera.ai/v1/",
|
||||||
|
"apiKey": "${TNG_API_KEY}",
|
||||||
|
"api": "openai-completions",
|
||||||
|
"models": [
|
||||||
|
{ "id": "tngtech/R1T2-Chimera-Speed", "name": "TNG Chimera Speed", "contextWindow": 65536, "maxTokens": 65536 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"minimax": {
|
||||||
|
"baseUrl": "https://api.minimax.io/anthropic",
|
||||||
|
"apiKey": "${MINIMAX_API_KEY}",
|
||||||
|
"api": "anthropic-messages",
|
||||||
|
"models": [
|
||||||
|
{ "id": "MiniMax-M2.7", "name": "MiniMax M2.7", "contextWindow": 200000, "maxTokens": 32768, "reasoning": true },
|
||||||
|
{ "id": "MiniMax-M2.5", "name": "MiniMax M2.5", "contextWindow": 200000, "maxTokens": 32768, "reasoning": true },
|
||||||
|
{ "id": "MiniMax-M2.5-highspeed", "name": "MiniMax M2.5 Highspeed", "contextWindow": 200000, "maxTokens": 32768, "reasoning": true },
|
||||||
|
{ "id": "MiniMax-VL-01", "name": "MiniMax VL 01", "contextWindow": 200000, "maxTokens": 32768 }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ in
|
||||||
for skill_file in $REPO_SRC/skills/openclaw-native/*/SKILL.md; do
|
for skill_file in $REPO_SRC/skills/openclaw-native/*/SKILL.md; do
|
||||||
[ -f "$skill_file" ] || continue
|
[ -f "$skill_file" ] || continue
|
||||||
skill_name=$(basename $(dirname "$skill_file"))
|
skill_name=$(basename $(dirname "$skill_file"))
|
||||||
|
|
||||||
# Check if stateful: true in frontmatter
|
# Check if stateful: true in frontmatter
|
||||||
if sed -n '2,/^---$/p' "$skill_file" | grep -q '^stateful: *true'; then
|
if sed -n '2,/^---$/p' "$skill_file" | grep -q '^stateful: *true'; then
|
||||||
mkdir -p "/var/lib/openclaw/skill-state/$skill_name"
|
mkdir -p "/var/lib/openclaw/skill-state/$skill_name"
|
||||||
|
|
@ -102,6 +102,18 @@ in
|
||||||
''}
|
''}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
# Set git email for the node user inside the container
|
||||||
|
systemd.services."openclaw-git-config" = {
|
||||||
|
description = "Configure git email for OpenClaw node user";
|
||||||
|
after = [ "podman-openclaw.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "${pkgs.podman}/bin/podman exec -u node openclaw git config --global user.email 'kafka@ashisgreat.xyz'";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# Go toolchain installation script
|
# Go toolchain installation script
|
||||||
# Stored in /var/lib/openclaw and executed inside the container
|
# Stored in /var/lib/openclaw and executed inside the container
|
||||||
environment.etc."openclaw/install-go.sh".source = pkgs.writeScript "install-go.sh" ''
|
environment.etc."openclaw/install-go.sh".source = pkgs.writeScript "install-go.sh" ''
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ forgejo_user: ENC[AES256_GCM,data:Ralbwu6+6Htc2+I=,iv:dicPMRRriz6MVp0PtbezI6Ucxd
|
||||||
github_token: ENC[AES256_GCM,data:OAh6v6xrLr47ZdytdSR4uBpj6vJB8kJa8qc3eFBByK53nkrb3SUuBQ==,iv:GM/DpFSVl1CeQLX4tH2WxBuWBbI1YWzSsmvZK+2jdWM=,tag:lPQSjIlYbe3AczfDN3Nk+g==,type:str]
|
github_token: ENC[AES256_GCM,data:OAh6v6xrLr47ZdytdSR4uBpj6vJB8kJa8qc3eFBByK53nkrb3SUuBQ==,iv:GM/DpFSVl1CeQLX4tH2WxBuWBbI1YWzSsmvZK+2jdWM=,tag:lPQSjIlYbe3AczfDN3Nk+g==,type:str]
|
||||||
openwebui_secret_key: ENC[AES256_GCM,data:c1Mnc0juYBAmHap3f0G5vwRDUymYWb92nIk78Rw5ApkhhW4k4ifRccCsv0fU2TXNSwHCc7d6OeP60kJYEpr5ZA==,iv:wCqfwhn6WFv3A0asZnbPdBdmw24QdKbJE0BplWzq9CE=,tag:WU8Rlyf+CIL2uG8yWKHjcw==,type:str]
|
openwebui_secret_key: ENC[AES256_GCM,data:c1Mnc0juYBAmHap3f0G5vwRDUymYWb92nIk78Rw5ApkhhW4k4ifRccCsv0fU2TXNSwHCc7d6OeP60kJYEpr5ZA==,iv:wCqfwhn6WFv3A0asZnbPdBdmw24QdKbJE0BplWzq9CE=,tag:WU8Rlyf+CIL2uG8yWKHjcw==,type:str]
|
||||||
tng_api_key: ENC[AES256_GCM,data:KxfGd46SSp13zo1IxchDVq8dY7wTReyAS58JTIqJbv10YoXKY2fq4R4o6EaWSqyJC+k=,iv:QBVLbDDV94pwsHSngABiL17wVcHYNTUBtoOvQgg8Fcc=,tag:A/4Ieeb1nIKVEJ6FVL6gJQ==,type:str]
|
tng_api_key: ENC[AES256_GCM,data:KxfGd46SSp13zo1IxchDVq8dY7wTReyAS58JTIqJbv10YoXKY2fq4R4o6EaWSqyJC+k=,iv:QBVLbDDV94pwsHSngABiL17wVcHYNTUBtoOvQgg8Fcc=,tag:A/4Ieeb1nIKVEJ6FVL6gJQ==,type:str]
|
||||||
|
minimax_api_key: ENC[AES256_GCM,data:Y3jwwI7HvGKYZcBtgfjZWzs01rc7LMsBPlaVj1fnU4jBtF8wL0vVll9dTFENuJeCjmt35g1c5/7XtLe8T4s+A3w5LeRxAXsnGB7dM0mzxPf4EvKPCUdH+XuIpA4Iih1DbO0dO2H0/qSEg/Q9aucJusZ2mWcaT7meolccGp8=,iv:JkJYFP5N27QVkoLTOViIJYoHub66JV0ziY8ahzdL2lA=,tag:/aTyuzAdAtFCBoxg0SLYKw==,type:str]
|
||||||
sops:
|
sops:
|
||||||
age:
|
age:
|
||||||
- recipient: age1rz4eyzmmtmua6s9cny3pjjwv80n4fpvhkwc4jzdd8vpre8zc5vtqfjtuy0
|
- recipient: age1rz4eyzmmtmua6s9cny3pjjwv80n4fpvhkwc4jzdd8vpre8zc5vtqfjtuy0
|
||||||
|
|
@ -27,7 +28,7 @@ sops:
|
||||||
SnI3Z3p6U0x1YzVUTHZ0RVh0cHBDSGMKbDXwp9MM9cL/9DgWPV/btH6iYgaVXmvw
|
SnI3Z3p6U0x1YzVUTHZ0RVh0cHBDSGMKbDXwp9MM9cL/9DgWPV/btH6iYgaVXmvw
|
||||||
Gk4IsH7zEWbS1kxIEapzBpIINTSQKZ30aPqwuspVKdSa8lsfi1X1jA==
|
Gk4IsH7zEWbS1kxIEapzBpIINTSQKZ30aPqwuspVKdSa8lsfi1X1jA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2026-03-20T23:38:03Z"
|
lastmodified: "2026-03-21T23:33:40Z"
|
||||||
mac: ENC[AES256_GCM,data:B9s77SPIEI22K1QVyE4iUx9sDlPph7jbGVP2R5ulA+LU0ctjVqybvQQIepY1lN7OmnOVteK1Ed3B+BlqxlYhotZgTU14Sjh0fy5NKViLG2eQOJRbMoYPSXL7aLugGkfhTWr0qvdR9O4S4e6jR2AFWfp07x+HRSM95hKKCKgOFYI=,iv:TBAICXdmp0L4iAbAbST1K9/eysqNq3gqRy1mrMOap9o=,tag:eqBRamo+TdE6wleiiZC3eQ==,type:str]
|
mac: ENC[AES256_GCM,data:CkwgWZPkxHolLemYlLsK2YD/Y7W+3m9443TNCjuvW9jP2hYzgjgL5UYxfltRZFkR2zL7Cy7yPsWOSbIKMY5wXMX6isOgtfPyTYG3rBZ8mR3l4iACeDtE58yVJXclXjcg81oJW8HUpgIcWPGrANtLqiqOdGxHd9e3eGaXZV+zfoU=,iv:mlEEmP0JMod+x0r2mzanyFQf2o7wxYxJoh10Pj2ebyM=,tag:DgNd3kG1G6L2mx4jwFZxWQ==,type:str]
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.12.1
|
version: 3.12.1
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue