Skip to content

Commit 3b4d8d1

Browse files
authored
Merge pull request #3176 from semaphoreui/fix_key_installer_for_runner
fix(runner): key installer
2 parents 137e27f + d128e60 commit 3b4d8d1

File tree

13 files changed

+143
-147
lines changed

13 files changed

+143
-147
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@ web/public/html/**/*.*
77
web/public/fonts/*.*
88
web/.nyc_output
99
api/public/**/*
10+
/server.json
1011
/config.json
1112
/config.runner.json
1213
/config.runner.token
1314
/config.runner.key
15+
/runner.json
16+
/runner.token
17+
/runner.key
1418
/.dredd/config.json
1519
/database.boltdb
1620
/database.sqlite

cli/cmd/runner.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
package cmd
22

33
import (
4+
"github.com/semaphoreui/semaphore/pkg/ssh"
5+
"github.com/semaphoreui/semaphore/services/runners"
46
"github.com/spf13/cobra"
57
"os"
68
)
79

10+
func createRunnerJobPool() *runners.JobPool {
11+
return runners.NewJobPool(&ssh.KeyInstaller{})
12+
}
13+
814
func init() {
915
rootCmd.AddCommand(runnerCmd)
1016
}

cli/cmd/runner_register.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"os"
66
"strings"
77

8-
"github.com/semaphoreui/semaphore/services/runners"
98
"github.com/semaphoreui/semaphore/util"
109
"github.com/spf13/cobra"
1110
)
@@ -36,7 +35,7 @@ func registerRunner() {
3635
util.Config.Runner.RegistrationToken = strings.TrimSpace(string(tokenBytes))
3736
}
3837

39-
taskPool := runners.JobPool{}
38+
taskPool := createRunnerJobPool()
4039

4140
err := taskPool.Register(configFile)
4241

cli/cmd/runner_setup.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package cmd
33
import (
44
"fmt"
55
"github.com/semaphoreui/semaphore/cli/setup"
6-
"github.com/semaphoreui/semaphore/services/runners"
76
"github.com/semaphoreui/semaphore/util"
87
"github.com/spf13/cobra"
98
)
@@ -33,7 +32,7 @@ func doRunnerSetup() int {
3332
}
3433

3534
if util.Config.Runner.RegistrationToken != "" {
36-
taskPool := runners.JobPool{}
35+
taskPool := createRunnerJobPool()
3736
err := taskPool.Register(&resultConfigPath)
3837
if err != nil {
3938
panic(err)

cli/cmd/runner_start.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package cmd
22

33
import (
4-
"github.com/semaphoreui/semaphore/services/runners"
54
"github.com/semaphoreui/semaphore/util"
65
"github.com/spf13/cobra"
76
)
@@ -13,7 +12,7 @@ func init() {
1312
func runRunner() {
1413
util.ConfigInit(persistentFlags.configPath, persistentFlags.noConfig)
1514

16-
taskPool := runners.JobPool{}
15+
taskPool := createRunnerJobPool()
1716

1817
taskPool.Run()
1918
}

cli/cmd/runner_unregister.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package cmd
22

33
import (
4-
"github.com/semaphoreui/semaphore/services/runners"
54
"github.com/semaphoreui/semaphore/util"
65
"github.com/spf13/cobra"
76
)
@@ -13,7 +12,7 @@ func init() {
1312
func unregisterRunner() {
1413
util.ConfigInit(persistentFlags.configPath, persistentFlags.noConfig)
1514

16-
taskPool := runners.JobPool{}
15+
taskPool := createRunnerJobPool()
1716
err := taskPool.Unregister()
1817
if err != nil {
1918
panic(err)

db/AccessKey.go

Lines changed: 4 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ package db
22

33
import (
44
"fmt"
5-
"github.com/semaphoreui/semaphore/pkg/random"
6-
"github.com/semaphoreui/semaphore/pkg/ssh"
7-
"github.com/semaphoreui/semaphore/pkg/task_logger"
8-
"github.com/semaphoreui/semaphore/util"
9-
"path"
5+
//"github.com/semaphoreui/semaphore/pkg/ssh"
6+
//"github.com/semaphoreui/semaphore/pkg/random"
7+
//"github.com/semaphoreui/semaphore/pkg/ssh"
8+
//"path"
109
)
1110

1211
type AccessKeyType string
@@ -80,62 +79,6 @@ const (
8079
AccessKeyRoleGit
8180
)
8281

83-
type AccessKeyInstallation struct {
84-
SSHAgent *ssh.Agent
85-
Login string
86-
Password string
87-
Script string
88-
}
89-
90-
func (key *AccessKeyInstallation) GetGitEnv() (env []string) {
91-
env = make([]string, 0)
92-
93-
env = append(env, fmt.Sprintln("GIT_TERMINAL_PROMPT=0"))
94-
if key.SSHAgent != nil {
95-
env = append(env, fmt.Sprintf("SSH_AUTH_SOCK=%s", key.SSHAgent.SocketFile))
96-
sshCmd := "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
97-
if util.Config.SshConfigPath != "" {
98-
sshCmd += " -F " + util.Config.SshConfigPath
99-
}
100-
env = append(env, fmt.Sprintf("GIT_SSH_COMMAND=%s", sshCmd))
101-
}
102-
103-
return env
104-
}
105-
106-
func (key *AccessKeyInstallation) Destroy() error {
107-
if key.SSHAgent != nil {
108-
return key.SSHAgent.Close()
109-
}
110-
return nil
111-
}
112-
113-
func (key *AccessKey) startSSHAgent(logger task_logger.Logger) (ssh.Agent, error) {
114-
115-
socketFilename := fmt.Sprintf("ssh-agent-%d-%s.sock", key.ID, random.String(10))
116-
117-
var socketFile string
118-
119-
if key.ProjectID == nil {
120-
socketFile = path.Join(util.Config.TmpPath, socketFilename)
121-
} else {
122-
socketFile = path.Join(util.Config.GetProjectTmpDir(*key.ProjectID), socketFilename)
123-
}
124-
125-
sshAgent := ssh.Agent{
126-
Logger: logger,
127-
Keys: []ssh.AgentKey{
128-
{
129-
Key: []byte(key.SshKey.PrivateKey),
130-
Passphrase: []byte(key.SshKey.Passphrase),
131-
},
132-
},
133-
SocketFile: socketFile,
134-
}
135-
136-
return sshAgent, sshAgent.Listen()
137-
}
138-
13982
func (key *AccessKey) Validate(validateSecretFields bool) error {
14083
if key.Name == "" {
14184
return fmt.Errorf("name can not be empty")

db_lib/AccessKeyInstaller.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ package db_lib
22

33
import (
44
"github.com/semaphoreui/semaphore/db"
5+
"github.com/semaphoreui/semaphore/pkg/ssh"
56
"github.com/semaphoreui/semaphore/pkg/task_logger"
67
)
78

89
type AccessKeyInstaller interface {
9-
Install(key db.AccessKey, usage db.AccessKeyRole, logger task_logger.Logger) (installation db.AccessKeyInstallation, err error)
10+
Install(key db.AccessKey, usage db.AccessKeyRole, logger task_logger.Logger) (installation ssh.AccessKeyInstallation, err error)
1011
}

db_lib/CmdGitClient.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package db_lib
22

33
import (
44
"fmt"
5+
"github.com/semaphoreui/semaphore/pkg/ssh"
56
"os/exec"
67
"strings"
78

@@ -16,7 +17,7 @@ type CmdGitClient struct {
1617
func (c CmdGitClient) makeCmd(
1718
r GitRepository,
1819
targetDir GitRepositoryDirType,
19-
installation db.AccessKeyInstallation,
20+
installation ssh.AccessKeyInstallation,
2021
args ...string,
2122
) *exec.Cmd {
2223
cmd := exec.Command("git") //nolint: gas

pkg/ssh/agent.go

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ package ssh
22

33
import (
44
"fmt"
5+
"github.com/semaphoreui/semaphore/db"
6+
"github.com/semaphoreui/semaphore/pkg/random"
7+
"github.com/semaphoreui/semaphore/util"
58
"io"
69
"net"
10+
"path"
711

812
"github.com/semaphoreui/semaphore/pkg/task_logger"
913
"golang.org/x/crypto/ssh"
@@ -95,6 +99,110 @@ func (a *Agent) Listen() error {
9599
}
96100

97101
func (a *Agent) Close() error {
98-
close(a.done)
102+
if a.done != nil {
103+
close(a.done)
104+
}
99105
return a.listener.Close()
100106
}
107+
108+
func StartSSHAgent(key db.AccessKey, logger task_logger.Logger) (Agent, error) {
109+
110+
socketFilename := fmt.Sprintf("ssh-agent-%d-%s.sock", key.ID, random.String(10))
111+
112+
var socketFile string
113+
114+
if key.ProjectID == nil {
115+
socketFile = path.Join(util.Config.TmpPath, socketFilename)
116+
} else {
117+
socketFile = path.Join(util.Config.GetProjectTmpDir(*key.ProjectID), socketFilename)
118+
}
119+
120+
sshAgent := Agent{
121+
Logger: logger,
122+
Keys: []AgentKey{
123+
{
124+
Key: []byte(key.SshKey.PrivateKey),
125+
Passphrase: []byte(key.SshKey.Passphrase),
126+
},
127+
},
128+
SocketFile: socketFile,
129+
}
130+
131+
return sshAgent, sshAgent.Listen()
132+
}
133+
134+
type AccessKeyInstallation struct {
135+
SSHAgent *Agent
136+
Login string
137+
Password string
138+
Script string
139+
}
140+
141+
func (key *AccessKeyInstallation) GetGitEnv() (env []string) {
142+
env = make([]string, 0)
143+
144+
env = append(env, fmt.Sprintln("GIT_TERMINAL_PROMPT=0"))
145+
if key.SSHAgent != nil {
146+
env = append(env, fmt.Sprintf("SSH_AUTH_SOCK=%s", key.SSHAgent.SocketFile))
147+
sshCmd := "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
148+
if util.Config.SshConfigPath != "" {
149+
sshCmd += " -F " + util.Config.SshConfigPath
150+
}
151+
env = append(env, fmt.Sprintf("GIT_SSH_COMMAND=%s", sshCmd))
152+
}
153+
154+
return env
155+
}
156+
157+
func (key *AccessKeyInstallation) Destroy() error {
158+
if key.SSHAgent != nil {
159+
return key.SSHAgent.Close()
160+
}
161+
return nil
162+
}
163+
164+
type KeyInstaller struct{}
165+
166+
func (KeyInstaller) Install(key db.AccessKey, usage db.AccessKeyRole, logger task_logger.Logger) (installation AccessKeyInstallation, err error) {
167+
168+
switch usage {
169+
case db.AccessKeyRoleGit:
170+
switch key.Type {
171+
case db.AccessKeySSH:
172+
var agent Agent
173+
agent, err = StartSSHAgent(key, logger)
174+
installation.SSHAgent = &agent
175+
installation.Login = key.SshKey.Login
176+
}
177+
case db.AccessKeyRoleAnsiblePasswordVault:
178+
switch key.Type {
179+
case db.AccessKeyLoginPassword:
180+
installation.Password = key.LoginPassword.Password
181+
default:
182+
err = fmt.Errorf("access key type not supported for ansible password vault")
183+
}
184+
case db.AccessKeyRoleAnsibleBecomeUser:
185+
if key.Type != db.AccessKeyLoginPassword {
186+
err = fmt.Errorf("access key type not supported for ansible become user")
187+
}
188+
installation.Login = key.LoginPassword.Login
189+
installation.Password = key.LoginPassword.Password
190+
case db.AccessKeyRoleAnsibleUser:
191+
switch key.Type {
192+
case db.AccessKeySSH:
193+
var agent Agent
194+
agent, err = StartSSHAgent(key, logger)
195+
installation.SSHAgent = &agent
196+
installation.Login = key.SshKey.Login
197+
case db.AccessKeyLoginPassword:
198+
installation.Login = key.LoginPassword.Login
199+
installation.Password = key.LoginPassword.Password
200+
case db.AccessKeyNone:
201+
// No SSH agent or password needed for ansible user with no access key.
202+
default:
203+
err = fmt.Errorf("access key type not supported for ansible user")
204+
}
205+
}
206+
207+
return
208+
}

0 commit comments

Comments
 (0)