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
|
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).
|
// cloneURL builds the clean https clone URL (never credential-bearing).
|
||||||
func (s *Spawner) cloneURL(repo string) (string, error) {
|
func (s *Spawner) cloneURL(repo string) (string, error) {
|
||||||
u, err := url.Parse(s.baseURL + "/" + repo + ".git")
|
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{
|
cfg := &container.Config{
|
||||||
Image: image,
|
Image: image,
|
||||||
Env: []string{
|
Env: workerEnv(s, repo, sessionID),
|
||||||
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,
|
|
||||||
},
|
|
||||||
Labels: map[string]string{labelSession: sessionID},
|
Labels: map[string]string{labelSession: sessionID},
|
||||||
}
|
}
|
||||||
hostCfg := &container.HostConfig{
|
hostCfg := &container.HostConfig{
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ func TestSpawnerStartHappyPath(t *testing.T) {
|
|||||||
passthrough := map[string]bool{
|
passthrough := map[string]bool{
|
||||||
"OPENAI_API_KEY": true, "GEMINI_API_KEY": true,
|
"OPENAI_API_KEY": true, "GEMINI_API_KEY": true,
|
||||||
"DEEPSEEK_KEY": true, "ANTHROPIC_API_KEY": true,
|
"DEEPSEEK_KEY": true, "ANTHROPIC_API_KEY": true,
|
||||||
|
"LVMH_GITEA_TOKEN": true,
|
||||||
}
|
}
|
||||||
for _, e := range c.Env {
|
for _, e := range c.Env {
|
||||||
if name, _, ok := strings.Cut(e, "="); ok && passthrough[name] {
|
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
|
Host alarm desk blanc-nas
|
||||||
IdentityFile /root/.ssh/id_ed25519
|
IdentityFile /root/.ssh/id_ed25519
|
||||||
IdentitiesOnly yes
|
IdentitiesOnly yes
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
# blanc-nas:22 SSH-2.0-OpenSSH_10.4
|
# 100.64.84.69:22 SSH-2.0-OpenSSH_10.4
|
||||||
blanc-nas ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7CmHNP4LxohSCJY1acgMqPPb0hvjlbDzzvf1oqPLcaGs+KsRL2+OfMbNHOMBz4XfM5WN5DANOCuOBJBtn1vyAu83JXLx0XTl6pEnmaBm6Wjs05zmI1fliGJHgbPsPCz8Y+kRNY1Z01VWWsanr7Yu9LStcyKY1v2i2DqQ9i3WdTzWyE9Tkt3540/49LFVjkRR6lGeh2G0/ppM3utM2Rg/CGMjbmYV9LBtU5CTtrEWiGLyDwxuXNyk6BcQkxOHZf76W05/FwvHRv15mwF0RxkDitmfzWMEQ/+paUcDMRgLKF1j2mBtR2UdR3z7m4q46PiXKAjyJAG7tIfJqwr1jSRYXn6+bEV5tK6VJkc2+0viMoQYrnBBxL676rShECG27Ib8loUk2PuhXUSVWiLY+/BvRyXETIZxgoF53LCO5Z0Wh91Dp2OMfO0EajfRc83FfqOFgwhGpVk27r+LcLjYzqz5BUIy58HtSpZEQRr1KJuagZFfnLDRtY9ovn3uBDQhpX0k=
|
100.64.84.69 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGIoBFYAfkN1Q8XsjwsJZ2mLIQi9XQ9M03zEENW8Injq
|
||||||
# blanc-nas:22 SSH-2.0-OpenSSH_10.4
|
# 100.73.57.3:22 SSH-2.0-OpenSSH_10.4
|
||||||
blanc-nas ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFB7p37Rxw6tW2rUpoECwtXLBnU179CxiwTNtwJQs7Sp
|
100.73.57.3 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN5kwgNZ/IYLpAxVtezTxYLcy7MmP9lKnrKX0XeBiCIn
|
||||||
# alarm:22 SSH-2.0-OpenSSH_10.4
|
# 100.91.19.107: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=
|
100.91.19.107 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFB7p37Rxw6tW2rUpoECwtXLBnU179CxiwTNtwJQs7Sp
|
||||||
# alarm:22 SSH-2.0-OpenSSH_10.4
|
|
||||||
alarm ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGIoBFYAfkN1Q8XsjwsJZ2mLIQi9XQ9M03zEENW8Injq
|
|
||||||
|
|||||||
Reference in New Issue
Block a user