feat: agent deploy pipeline — passwordless SSH (alarm/desk/blanc-nas via tailnet IPs in ssh config), gitea write token to workers, secrets mounts, gitconfig, APPEND_SYSTEM guide
This commit is contained in:
+32
-14
@@ -353,6 +353,36 @@ func (s *Spawner) cloneOrUpdate(ctx context.Context, repo, branch, slug string)
|
||||
return nil
|
||||
}
|
||||
|
||||
// giteaTokenEnv returns LVMH_GITEA_TOKEN=<pat> when a PAT is stored.
|
||||
func giteaTokenEnv(store *Store) string {
|
||||
if pat, ok, _ := store.GetSetting(settingGitLabToken); ok && pat != "" {
|
||||
return "LVMH_GITEA_TOKEN=" + pat
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// workerEnv assembles the env for a spawned worker container.
|
||||
func workerEnv(s *Spawner, repo, sessionID string) []string {
|
||||
env := []string{
|
||||
envProviderAPIKey + "=" + os.Getenv(envProviderAPIKey),
|
||||
envToken + "=" + daemonToken,
|
||||
"LVMH_URL=" + s.containerURL,
|
||||
envLVMHSessionID + "=" + sessionID,
|
||||
envLVMHAgent + "=1",
|
||||
// other provider keys (empty ones are harmless)
|
||||
"OPENAI_API_KEY=" + os.Getenv("OPENAI_API_KEY"),
|
||||
"GEMINI_API_KEY=" + os.Getenv("GEMINI_API_KEY"),
|
||||
"DEEPSEEK_KEY=" + os.Getenv("DEEPSEEK_KEY"),
|
||||
"ANTHROPIC_API_KEY=" + os.Getenv("ANTHROPIC_API_KEY"),
|
||||
envLVMHRepo + "=" + repo,
|
||||
}
|
||||
// Gitea token (write scope) so agents can push and open PRs.
|
||||
if e := giteaTokenEnv(s.store); e != "" {
|
||||
env = append(env, e)
|
||||
}
|
||||
return env
|
||||
}
|
||||
|
||||
// cloneURL builds the clean https clone URL (never credential-bearing).
|
||||
func (s *Spawner) cloneURL(repo string) (string, error) {
|
||||
u, err := url.Parse(s.baseURL + "/" + repo + ".git")
|
||||
@@ -536,20 +566,8 @@ func (s *Spawner) createAndStart(ctx context.Context, repo, slug, sessionID stri
|
||||
)
|
||||
}
|
||||
cfg := &container.Config{
|
||||
Image: image,
|
||||
Env: []string{
|
||||
envProviderAPIKey + "=" + os.Getenv(envProviderAPIKey),
|
||||
envToken + "=" + daemonToken,
|
||||
"LVMH_URL=" + s.containerURL,
|
||||
envLVMHSessionID + "=" + sessionID,
|
||||
envLVMHAgent + "=1",
|
||||
// other provider keys (empty ones are harmless)
|
||||
"OPENAI_API_KEY=" + os.Getenv("OPENAI_API_KEY"),
|
||||
"GEMINI_API_KEY=" + os.Getenv("GEMINI_API_KEY"),
|
||||
"DEEPSEEK_KEY=" + os.Getenv("DEEPSEEK_KEY"),
|
||||
"ANTHROPIC_API_KEY=" + os.Getenv("ANTHROPIC_API_KEY"),
|
||||
envLVMHRepo + "=" + repo,
|
||||
},
|
||||
Image: image,
|
||||
Env: workerEnv(s, repo, sessionID),
|
||||
Labels: map[string]string{labelSession: sessionID},
|
||||
}
|
||||
hostCfg := &container.HostConfig{
|
||||
|
||||
@@ -72,6 +72,7 @@ func TestSpawnerStartHappyPath(t *testing.T) {
|
||||
passthrough := map[string]bool{
|
||||
"OPENAI_API_KEY": true, "GEMINI_API_KEY": true,
|
||||
"DEEPSEEK_KEY": true, "ANTHROPIC_API_KEY": true,
|
||||
"LVMH_GITEA_TOKEN": true,
|
||||
}
|
||||
for _, e := range c.Env {
|
||||
if name, _, ok := strings.Cut(e, "="); ok && passthrough[name] {
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
Host alarm
|
||||
HostName 100.64.84.69
|
||||
User alarm
|
||||
Host desk
|
||||
HostName 100.73.57.3
|
||||
User raph
|
||||
Host blanc-nas
|
||||
HostName 100.91.19.107
|
||||
User raph
|
||||
Host alarm desk blanc-nas
|
||||
IdentityFile /root/.ssh/id_ed25519
|
||||
IdentitiesOnly yes
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
# blanc-nas:22 SSH-2.0-OpenSSH_10.4
|
||||
blanc-nas ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7CmHNP4LxohSCJY1acgMqPPb0hvjlbDzzvf1oqPLcaGs+KsRL2+OfMbNHOMBz4XfM5WN5DANOCuOBJBtn1vyAu83JXLx0XTl6pEnmaBm6Wjs05zmI1fliGJHgbPsPCz8Y+kRNY1Z01VWWsanr7Yu9LStcyKY1v2i2DqQ9i3WdTzWyE9Tkt3540/49LFVjkRR6lGeh2G0/ppM3utM2Rg/CGMjbmYV9LBtU5CTtrEWiGLyDwxuXNyk6BcQkxOHZf76W05/FwvHRv15mwF0RxkDitmfzWMEQ/+paUcDMRgLKF1j2mBtR2UdR3z7m4q46PiXKAjyJAG7tIfJqwr1jSRYXn6+bEV5tK6VJkc2+0viMoQYrnBBxL676rShECG27Ib8loUk2PuhXUSVWiLY+/BvRyXETIZxgoF53LCO5Z0Wh91Dp2OMfO0EajfRc83FfqOFgwhGpVk27r+LcLjYzqz5BUIy58HtSpZEQRr1KJuagZFfnLDRtY9ovn3uBDQhpX0k=
|
||||
# blanc-nas:22 SSH-2.0-OpenSSH_10.4
|
||||
blanc-nas ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFB7p37Rxw6tW2rUpoECwtXLBnU179CxiwTNtwJQs7Sp
|
||||
# alarm:22 SSH-2.0-OpenSSH_10.4
|
||||
alarm ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCwjQpOAwCL0AIGeJzI99CoOFTxUFUd2+DCveZKeBfCpdyZAtrPTd5310VjyAH0HWXd3c4fZvgPcrjSzzbygpSroZD9zQh6zadp+yCXZNoLrc2iT8CkSngw24QpvOfdkunJiwnRjKLflYrCvzu0BHAoDKHq8XjpTpwfN0BH/eoIIqcoDnmF9KrTUQRbEzwg+xc1T41ByjIalqHfrdNxV0S8xv+sQ7/YvGmi4YVZJ5ElqEEgGtyBDJE3WuveH5sA+YkdoMMEm9Xf+xlgO6uwhaYAKbG29Rkq9Ot8N7NSf3mu00XVK5wHvHLYqFBhA24Pw5fuDp0ohbhHKIbpumS5GP8Ow3eR/bLIesSGkaPnB4o6t8HiQ3TKfdCO8UAvH85j6gXDiPmFXybOmxQMB+oWo+zdOYa8XVryHB3CJ+4yBmJU03dzNwpV+93uVoW9jmjElRwZx9c+gqSBUWgWlaVF1AFdVT2swzKIBTJg2ZXjoqLphuWfnewhPKPt48Fr5B0OAYk=
|
||||
# alarm:22 SSH-2.0-OpenSSH_10.4
|
||||
alarm ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGIoBFYAfkN1Q8XsjwsJZ2mLIQi9XQ9M03zEENW8Injq
|
||||
# 100.64.84.69:22 SSH-2.0-OpenSSH_10.4
|
||||
100.64.84.69 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGIoBFYAfkN1Q8XsjwsJZ2mLIQi9XQ9M03zEENW8Injq
|
||||
# 100.73.57.3:22 SSH-2.0-OpenSSH_10.4
|
||||
100.73.57.3 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN5kwgNZ/IYLpAxVtezTxYLcy7MmP9lKnrKX0XeBiCIn
|
||||
# 100.91.19.107:22 SSH-2.0-OpenSSH_10.4
|
||||
100.91.19.107 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFB7p37Rxw6tW2rUpoECwtXLBnU179CxiwTNtwJQs7Sp
|
||||
|
||||
Reference in New Issue
Block a user