Merge pull request #16761 from spowelljr/sshAgent
Add ability to start & stop ssh-agent processpull/16800/head
commit
7ba7f7b868
|
@ -51,6 +51,7 @@ import (
|
|||
"k8s.io/minikube/pkg/minikube/out"
|
||||
"k8s.io/minikube/pkg/minikube/out/register"
|
||||
"k8s.io/minikube/pkg/minikube/reason"
|
||||
"k8s.io/minikube/pkg/minikube/sshagent"
|
||||
"k8s.io/minikube/pkg/minikube/style"
|
||||
)
|
||||
|
||||
|
@ -93,6 +94,9 @@ var hostAndDirsDeleter = func(api libmachine.API, cc *config.ClusterConfig, prof
|
|||
if err := killMountProcess(); err != nil {
|
||||
out.FailureT("Failed to kill mount process: {{.error}}", out.V{"error": err})
|
||||
}
|
||||
if err := sshagent.Stop(profileName); err != nil {
|
||||
out.FailureT("Failed to stop ssh-agent process: {{.error}}", out.V{"error": err})
|
||||
}
|
||||
|
||||
deleteHosts(api, cc)
|
||||
|
||||
|
|
|
@ -71,6 +71,12 @@ var dockerEnvTCPTmpl = fmt.Sprintf(
|
|||
"{{ if .NoProxyVar }}"+
|
||||
"{{ .Prefix }}{{ .NoProxyVar }}{{ .Delimiter }}{{ .NoProxyValue }}{{ .Suffix }}"+
|
||||
"{{ end }}"+
|
||||
"{{ if .SSHAuthSock }}"+
|
||||
"{{ .Prefix }}%s{{ .Delimiter }}{{ .SSHAuthSock }}{{ .Suffix }}"+
|
||||
"{{ end }}"+
|
||||
"{{ if .SSHAgentPID }}"+
|
||||
"{{ .Prefix }}%s{{ .Delimiter }}{{ .SSHAgentPID }}{{ .Suffix }}"+
|
||||
"{{ end }}"+
|
||||
"{{ .UsageHint }}",
|
||||
constants.DockerTLSVerifyEnv,
|
||||
constants.DockerHostEnv,
|
||||
|
@ -78,13 +84,23 @@ var dockerEnvTCPTmpl = fmt.Sprintf(
|
|||
constants.ExistingDockerTLSVerifyEnv,
|
||||
constants.ExistingDockerHostEnv,
|
||||
constants.ExistingDockerCertPathEnv,
|
||||
constants.MinikubeActiveDockerdEnv)
|
||||
constants.MinikubeActiveDockerdEnv,
|
||||
constants.SSHAuthSock,
|
||||
constants.SSHAgentPID)
|
||||
var dockerEnvSSHTmpl = fmt.Sprintf(
|
||||
"{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerHost }}{{ .Suffix }}"+
|
||||
"{{ .Prefix }}%s{{ .Delimiter }}{{ .MinikubeDockerdProfile }}{{ .Suffix }}"+
|
||||
"{{ if .SSHAuthSock }}"+
|
||||
"{{ .Prefix }}%s{{ .Delimiter }}{{ .SSHAuthSock }}{{ .Suffix }}"+
|
||||
"{{ end }}"+
|
||||
"{{ if .SSHAgentPID }}"+
|
||||
"{{ .Prefix }}%s{{ .Delimiter }}{{ .SSHAgentPID }}{{ .Suffix }}"+
|
||||
"{{ end }}"+
|
||||
"{{ .UsageHint }}",
|
||||
constants.DockerHostEnv,
|
||||
constants.MinikubeActiveDockerdEnv)
|
||||
constants.MinikubeActiveDockerdEnv,
|
||||
constants.SSHAuthSock,
|
||||
constants.SSHAgentPID)
|
||||
|
||||
// DockerShellConfig represents the shell config for Docker
|
||||
type DockerShellConfig struct {
|
||||
|
@ -99,6 +115,9 @@ type DockerShellConfig struct {
|
|||
ExistingDockerCertPath string
|
||||
ExistingDockerHost string
|
||||
ExistingDockerTLSVerify string
|
||||
|
||||
SSHAuthSock string
|
||||
SSHAgentPID string
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -142,6 +161,9 @@ func dockerShellCfgSet(ec DockerEnvConfig, envMap map[string]string) *DockerShel
|
|||
|
||||
s.MinikubeDockerdProfile = envMap[constants.MinikubeActiveDockerdEnv]
|
||||
|
||||
s.SSHAuthSock = envMap[constants.SSHAuthSock]
|
||||
s.SSHAgentPID = envMap[constants.SSHAgentPID]
|
||||
|
||||
if ec.noProxy {
|
||||
noProxyVar, noProxyValue := defaultNoProxyGetter.GetNoProxyVar()
|
||||
|
||||
|
@ -316,18 +338,20 @@ docker-cli install instructions: https://minikube.sigs.k8s.io/docs/tutorials/doc
|
|||
|
||||
hostIP := co.CP.IP.String()
|
||||
ec := DockerEnvConfig{
|
||||
EnvConfig: sh,
|
||||
profile: cname,
|
||||
driver: driverName,
|
||||
ssh: sshHost,
|
||||
hostIP: hostIP,
|
||||
port: port,
|
||||
certsDir: localpath.MakeMiniPath("certs"),
|
||||
noProxy: noProxy,
|
||||
username: d.GetSSHUsername(),
|
||||
hostname: hostname,
|
||||
sshport: sshport,
|
||||
keypath: d.GetSSHKeyPath(),
|
||||
EnvConfig: sh,
|
||||
profile: cname,
|
||||
driver: driverName,
|
||||
ssh: sshHost,
|
||||
hostIP: hostIP,
|
||||
port: port,
|
||||
certsDir: localpath.MakeMiniPath("certs"),
|
||||
noProxy: noProxy,
|
||||
username: d.GetSSHUsername(),
|
||||
hostname: hostname,
|
||||
sshport: sshport,
|
||||
keypath: d.GetSSHKeyPath(),
|
||||
sshAuthSock: co.Config.SSHAuthSock,
|
||||
sshAgentPID: co.Config.SSHAgentPID,
|
||||
}
|
||||
|
||||
dockerPath, err := exec.LookPath("docker")
|
||||
|
@ -371,17 +395,19 @@ docker-cli install instructions: https://minikube.sigs.k8s.io/docs/tutorials/doc
|
|||
// DockerEnvConfig encapsulates all external inputs into shell generation for Docker
|
||||
type DockerEnvConfig struct {
|
||||
shell.EnvConfig
|
||||
profile string
|
||||
driver string
|
||||
ssh bool
|
||||
hostIP string
|
||||
port int
|
||||
certsDir string
|
||||
noProxy bool
|
||||
username string
|
||||
hostname string
|
||||
sshport int
|
||||
keypath string
|
||||
profile string
|
||||
driver string
|
||||
ssh bool
|
||||
hostIP string
|
||||
port int
|
||||
certsDir string
|
||||
noProxy bool
|
||||
username string
|
||||
hostname string
|
||||
sshport int
|
||||
keypath string
|
||||
sshAuthSock string
|
||||
sshAgentPID int
|
||||
}
|
||||
|
||||
// dockerSetScript writes out a shell-compatible 'docker-env' script
|
||||
|
@ -497,11 +523,18 @@ func sshURL(username string, hostname string, port int) string {
|
|||
|
||||
// dockerEnvVars gets the necessary docker env variables to allow the use of minikube's docker daemon
|
||||
func dockerEnvVars(ec DockerEnvConfig) map[string]string {
|
||||
agentPID := strconv.Itoa(ec.sshAgentPID)
|
||||
// set agentPID to nil value if not set
|
||||
if agentPID == "0" {
|
||||
agentPID = ""
|
||||
}
|
||||
envTCP := map[string]string{
|
||||
constants.DockerTLSVerifyEnv: "1",
|
||||
constants.DockerHostEnv: dockerURL(ec.hostIP, ec.port),
|
||||
constants.DockerCertPathEnv: ec.certsDir,
|
||||
constants.MinikubeActiveDockerdEnv: ec.profile,
|
||||
constants.SSHAuthSock: ec.sshAuthSock,
|
||||
constants.SSHAgentPID: agentPID,
|
||||
}
|
||||
envSSH := map[string]string{
|
||||
constants.DockerHostEnv: sshURL(ec.username, ec.hostname, ec.sshport),
|
||||
|
@ -532,6 +565,8 @@ func dockerEnvNames(ec DockerEnvConfig) []string {
|
|||
constants.DockerHostEnv,
|
||||
constants.DockerCertPathEnv,
|
||||
constants.MinikubeActiveDockerdEnv,
|
||||
constants.SSHAuthSock,
|
||||
constants.SSHAgentPID,
|
||||
}
|
||||
|
||||
if ec.noProxy {
|
||||
|
@ -550,6 +585,8 @@ func dockerEnvVarsList(ec DockerEnvConfig) []string {
|
|||
fmt.Sprintf("%s=%s", constants.DockerHostEnv, dockerURL(ec.hostIP, ec.port)),
|
||||
fmt.Sprintf("%s=%s", constants.DockerCertPathEnv, ec.certsDir),
|
||||
fmt.Sprintf("%s=%s", constants.MinikubeActiveDockerdEnv, ec.profile),
|
||||
fmt.Sprintf("%s=%s", constants.SSHAuthSock, ec.sshAuthSock),
|
||||
fmt.Sprintf("%s=%d", constants.SSHAgentPID, ec.sshAgentPID),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,8 @@ export MINIKUBE_ACTIVE_DOCKERD="dockerdriver"
|
|||
unset DOCKER_HOST;
|
||||
unset DOCKER_CERT_PATH;
|
||||
unset MINIKUBE_ACTIVE_DOCKERD;
|
||||
unset SSH_AUTH_SOCK;
|
||||
unset SSH_AGENT_PID;
|
||||
`,
|
||||
nil,
|
||||
},
|
||||
|
@ -81,6 +83,8 @@ export MINIKUBE_ACTIVE_DOCKERD="dockerdriver"
|
|||
unset DOCKER_HOST;
|
||||
unset DOCKER_CERT_PATH;
|
||||
unset MINIKUBE_ACTIVE_DOCKERD;
|
||||
unset SSH_AUTH_SOCK;
|
||||
unset SSH_AGENT_PID;
|
||||
`,
|
||||
nil,
|
||||
},
|
||||
|
@ -101,6 +105,8 @@ export MINIKUBE_ACTIVE_DOCKERD="bash"
|
|||
unset DOCKER_HOST;
|
||||
unset DOCKER_CERT_PATH;
|
||||
unset MINIKUBE_ACTIVE_DOCKERD;
|
||||
unset SSH_AUTH_SOCK;
|
||||
unset SSH_AGENT_PID;
|
||||
`,
|
||||
nil,
|
||||
},
|
||||
|
@ -121,6 +127,8 @@ export MINIKUBE_ACTIVE_DOCKERD="ipv6"
|
|||
unset DOCKER_HOST;
|
||||
unset DOCKER_CERT_PATH;
|
||||
unset MINIKUBE_ACTIVE_DOCKERD;
|
||||
unset SSH_AUTH_SOCK;
|
||||
unset SSH_AGENT_PID;
|
||||
`,
|
||||
nil,
|
||||
},
|
||||
|
@ -141,6 +149,8 @@ set -gx MINIKUBE_ACTIVE_DOCKERD "fish";
|
|||
set -e DOCKER_HOST;
|
||||
set -e DOCKER_CERT_PATH;
|
||||
set -e MINIKUBE_ACTIVE_DOCKERD;
|
||||
set -e SSH_AUTH_SOCK;
|
||||
set -e SSH_AGENT_PID;
|
||||
`,
|
||||
nil,
|
||||
},
|
||||
|
@ -161,6 +171,8 @@ $Env:MINIKUBE_ACTIVE_DOCKERD = "powershell"
|
|||
Remove-Item Env:\\DOCKER_HOST
|
||||
Remove-Item Env:\\DOCKER_CERT_PATH
|
||||
Remove-Item Env:\\MINIKUBE_ACTIVE_DOCKERD
|
||||
Remove-Item Env:\\SSH_AUTH_SOCK
|
||||
Remove-Item Env:\\SSH_AGENT_PID
|
||||
`,
|
||||
nil,
|
||||
},
|
||||
|
@ -181,6 +193,8 @@ REM @FOR /f "tokens=*" %i IN ('minikube -p cmd docker-env --shell cmd') DO @%i
|
|||
SET DOCKER_HOST=
|
||||
SET DOCKER_CERT_PATH=
|
||||
SET MINIKUBE_ACTIVE_DOCKERD=
|
||||
SET SSH_AUTH_SOCK=
|
||||
SET SSH_AGENT_PID=
|
||||
`,
|
||||
nil,
|
||||
},
|
||||
|
@ -200,6 +214,8 @@ SET MINIKUBE_ACTIVE_DOCKERD=
|
|||
(setenv "DOCKER_HOST" nil)
|
||||
(setenv "DOCKER_CERT_PATH" nil)
|
||||
(setenv "MINIKUBE_ACTIVE_DOCKERD" nil)
|
||||
(setenv "SSH_AUTH_SOCK" nil)
|
||||
(setenv "SSH_AGENT_PID" nil)
|
||||
`,
|
||||
nil,
|
||||
},
|
||||
|
@ -222,6 +238,8 @@ export NO_PROXY="127.0.0.1"
|
|||
unset DOCKER_HOST;
|
||||
unset DOCKER_CERT_PATH;
|
||||
unset MINIKUBE_ACTIVE_DOCKERD;
|
||||
unset SSH_AUTH_SOCK;
|
||||
unset SSH_AGENT_PID;
|
||||
unset NO_PROXY;
|
||||
`,
|
||||
nil,
|
||||
|
@ -245,6 +263,8 @@ export no_proxy="127.0.0.1"
|
|||
unset DOCKER_HOST;
|
||||
unset DOCKER_CERT_PATH;
|
||||
unset MINIKUBE_ACTIVE_DOCKERD;
|
||||
unset SSH_AUTH_SOCK;
|
||||
unset SSH_AGENT_PID;
|
||||
unset no_proxy;
|
||||
`,
|
||||
nil,
|
||||
|
@ -267,6 +287,8 @@ $Env:no_proxy = "192.168.0.1"
|
|||
Remove-Item Env:\\DOCKER_HOST
|
||||
Remove-Item Env:\\DOCKER_CERT_PATH
|
||||
Remove-Item Env:\\MINIKUBE_ACTIVE_DOCKERD
|
||||
Remove-Item Env:\\SSH_AUTH_SOCK
|
||||
Remove-Item Env:\\SSH_AGENT_PID
|
||||
Remove-Item Env:\\no_proxy
|
||||
`,
|
||||
nil,
|
||||
|
@ -290,6 +312,8 @@ export NO_PROXY="192.168.0.1,10.0.0.4,127.0.0.1"
|
|||
unset DOCKER_HOST;
|
||||
unset DOCKER_CERT_PATH;
|
||||
unset MINIKUBE_ACTIVE_DOCKERD;
|
||||
unset SSH_AUTH_SOCK;
|
||||
unset SSH_AGENT_PID;
|
||||
unset NO_PROXY;
|
||||
`,
|
||||
nil,
|
||||
|
@ -308,23 +332,29 @@ MINIKUBE_ACTIVE_DOCKERD=noneshell
|
|||
DOCKER_HOST
|
||||
DOCKER_CERT_PATH
|
||||
MINIKUBE_ACTIVE_DOCKERD
|
||||
SSH_AUTH_SOCK
|
||||
SSH_AGENT_PID
|
||||
`,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"none",
|
||||
"text",
|
||||
DockerEnvConfig{profile: "nonetext", driver: "docker", hostIP: "127.0.0.1", port: 32842, certsDir: "/certs"},
|
||||
DockerEnvConfig{profile: "nonetext", driver: "docker", hostIP: "127.0.0.1", port: 32842, certsDir: "/certs", sshAuthSock: "/var/folders/9l/6wpxv6wd1b901m1146r579wc00rqw3/T//ssh-KCQt1sNqrCPI/agent.29227", sshAgentPID: 29228},
|
||||
nil,
|
||||
`DOCKER_TLS_VERIFY=1
|
||||
DOCKER_HOST=tcp://127.0.0.1:32842
|
||||
DOCKER_CERT_PATH=/certs
|
||||
MINIKUBE_ACTIVE_DOCKERD=nonetext
|
||||
SSH_AUTH_SOCK=/var/folders/9l/6wpxv6wd1b901m1146r579wc00rqw3/T//ssh-KCQt1sNqrCPI/agent.29227
|
||||
SSH_AGENT_PID=29228
|
||||
`,
|
||||
`DOCKER_TLS_VERIFY
|
||||
DOCKER_HOST
|
||||
DOCKER_CERT_PATH
|
||||
MINIKUBE_ACTIVE_DOCKERD
|
||||
SSH_AUTH_SOCK
|
||||
SSH_AGENT_PID
|
||||
`,
|
||||
[]cmp.Option{
|
||||
cmpopts.AcyclicTransformer("SplitLines", func(s string) []string {
|
||||
|
@ -338,19 +368,23 @@ MINIKUBE_ACTIVE_DOCKERD
|
|||
{
|
||||
"none",
|
||||
"json",
|
||||
DockerEnvConfig{profile: "nonejson", driver: "docker", hostIP: "127.0.0.1", port: 32842, certsDir: "/certs"},
|
||||
DockerEnvConfig{profile: "nonejson", driver: "docker", hostIP: "127.0.0.1", port: 32842, certsDir: "/certs", sshAuthSock: "/var/folders/9l/6wpxv6wd1b901m1146r579wc00rqw3/T//ssh-KCQt1sNqrCPI/agent.29227", sshAgentPID: 29228},
|
||||
nil,
|
||||
`{
|
||||
"DOCKER_TLS_VERIFY": "1",
|
||||
"DOCKER_HOST": "tcp://127.0.0.1:32842",
|
||||
"DOCKER_CERT_PATH": "/certs",
|
||||
"MINIKUBE_ACTIVE_DOCKERD": "nonejson"
|
||||
"MINIKUBE_ACTIVE_DOCKERD": "nonejson",
|
||||
"SSH_AUTH_SOCK": "/var/folders/9l/6wpxv6wd1b901m1146r579wc00rqw3/T//ssh-KCQt1sNqrCPI/agent.29227",
|
||||
"SSH_AGENT_PID": "29228"
|
||||
}`,
|
||||
`[
|
||||
"DOCKER_TLS_VERIFY",
|
||||
"DOCKER_HOST",
|
||||
"DOCKER_CERT_PATH",
|
||||
"MINIKUBE_ACTIVE_DOCKERD"
|
||||
"MINIKUBE_ACTIVE_DOCKERD",
|
||||
"SSH_AUTH_SOCK",
|
||||
"SSH_AGENT_PID"
|
||||
]`,
|
||||
[]cmp.Option{
|
||||
cmp.FilterValues(func(x, y string) bool {
|
||||
|
@ -367,17 +401,21 @@ MINIKUBE_ACTIVE_DOCKERD
|
|||
{
|
||||
"none",
|
||||
"yaml",
|
||||
DockerEnvConfig{profile: "noneyaml", driver: "docker", hostIP: "127.0.0.1", port: 32842, certsDir: "/certs"},
|
||||
DockerEnvConfig{profile: "noneyaml", driver: "docker", hostIP: "127.0.0.1", port: 32842, certsDir: "/certs", sshAuthSock: "/var/folders/9l/6wpxv6wd1b901m1146r579wc00rqw3/T//ssh-KCQt1sNqrCPI/agent.29227", sshAgentPID: 29228},
|
||||
nil,
|
||||
`DOCKER_TLS_VERIFY: "1"
|
||||
DOCKER_HOST: tcp://127.0.0.1:32842
|
||||
DOCKER_CERT_PATH: /certs
|
||||
MINIKUBE_ACTIVE_DOCKERD: noneyaml
|
||||
SSH_AUTH_SOCK: /var/folders/9l/6wpxv6wd1b901m1146r579wc00rqw3/T//ssh-KCQt1sNqrCPI/agent.29227
|
||||
SSH_AGENT_PID: "29228"
|
||||
`,
|
||||
`- DOCKER_TLS_VERIFY
|
||||
- DOCKER_HOST
|
||||
- DOCKER_CERT_PATH
|
||||
- MINIKUBE_ACTIVE_DOCKERD
|
||||
- SSH_AUTH_SOCK
|
||||
- SSH_AGENT_PID
|
||||
`,
|
||||
[]cmp.Option{
|
||||
cmpopts.AcyclicTransformer("ParseYAML", func(in string) (out interface{}) {
|
||||
|
|
|
@ -105,6 +105,8 @@ type ClusterConfig struct {
|
|||
SocketVMnetClientPath string
|
||||
SocketVMnetPath string
|
||||
StaticIP string
|
||||
SSHAuthSock string
|
||||
SSHAgentPID int
|
||||
}
|
||||
|
||||
// KubernetesConfig contains the parameters used to configure the VM Kubernetes.
|
||||
|
|
|
@ -92,6 +92,10 @@ const (
|
|||
// MinikubeActiveDockerdEnv holds the docker daemon which user's shell is pointing at
|
||||
// value would be profile or empty if pointing to the user's host daemon.
|
||||
MinikubeActiveDockerdEnv = "MINIKUBE_ACTIVE_DOCKERD"
|
||||
// SSHAuthSock is used for docker-env
|
||||
SSHAuthSock = "SSH_AUTH_SOCK"
|
||||
// SSHAgentPID is used for docker-env
|
||||
SSHAgentPID = "SSH_AGENT_PID"
|
||||
// PodmanVarlinkBridgeEnv is used for podman settings
|
||||
PodmanVarlinkBridgeEnv = "PODMAN_VARLINK_BRIDGE"
|
||||
// PodmanContainerHostEnv is used for podman settings
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
Copyright 2023 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sshagent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/go-ps"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
)
|
||||
|
||||
type sshAgent struct {
|
||||
authSock string
|
||||
agentPID int
|
||||
}
|
||||
|
||||
// Start an ssh-agent process
|
||||
func Start(profile string) error {
|
||||
if runtime.GOOS == "windows" {
|
||||
return fmt.Errorf("starting an SSH agent on Windows is not yet supported")
|
||||
}
|
||||
cc, err := config.Load(profile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed loading config: %v", err)
|
||||
}
|
||||
running, err := isRunning(cc)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed checking if SSH agent is running: %v", err)
|
||||
}
|
||||
if running {
|
||||
klog.Info("SSH agent is already running, aborting start")
|
||||
return nil
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
out, err := exec.CommandContext(ctx, "ssh-agent").CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed starting ssh-agent: %s: %v", string(out), err)
|
||||
}
|
||||
parsed, err := parseOutput(string(out))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse ssh-agent output: %v", err)
|
||||
}
|
||||
cc.SSHAuthSock = parsed.authSock
|
||||
cc.SSHAgentPID = parsed.agentPID
|
||||
if err := config.Write(profile, cc); err != nil {
|
||||
return fmt.Errorf("failed writing config: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseOutput(out string) (*sshAgent, error) {
|
||||
sockSubmatches := regexp.MustCompile(`SSH_AUTH_SOCK=(.*?);`).FindStringSubmatch(out)
|
||||
if len(sockSubmatches) < 2 {
|
||||
return nil, fmt.Errorf("SSH_AUTH_SOCK not found in output: %s", out)
|
||||
}
|
||||
pidSubmatches := regexp.MustCompile(`SSH_AGENT_PID=(.*?);`).FindStringSubmatch(out)
|
||||
if len(pidSubmatches) < 2 {
|
||||
return nil, fmt.Errorf("SSH_AGENT_PID not found in output: %s", out)
|
||||
}
|
||||
pid, err := strconv.Atoi(pidSubmatches[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert pid to int: %v", err)
|
||||
}
|
||||
return &sshAgent{sockSubmatches[1], pid}, nil
|
||||
}
|
||||
|
||||
func isRunning(cc *config.ClusterConfig) (bool, error) {
|
||||
if cc.SSHAgentPID == 0 {
|
||||
return false, nil
|
||||
}
|
||||
entry, err := ps.FindProcess(cc.SSHAgentPID)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed finding process: %v", err)
|
||||
}
|
||||
if entry == nil {
|
||||
return false, nil
|
||||
}
|
||||
return strings.Contains(entry.Executable(), "ssh-agent"), nil
|
||||
}
|
||||
|
||||
// Stop an ssh-agent process
|
||||
func Stop(profile string) error {
|
||||
cc, err := config.Load(profile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed loading config: %v", err)
|
||||
}
|
||||
running, err := isRunning(cc)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed checking if SSH agent is running: %v", err)
|
||||
}
|
||||
if running {
|
||||
if err := killProcess(cc.SSHAgentPID); err != nil {
|
||||
return fmt.Errorf("failed killing SSH agent process: %v", err)
|
||||
}
|
||||
}
|
||||
cc.SSHAuthSock = ""
|
||||
cc.SSHAgentPID = 0
|
||||
if err := config.Write(profile, cc); err != nil {
|
||||
return fmt.Errorf("failed writing config: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func killProcess(pid int) error {
|
||||
proc, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed finding process: %v", err)
|
||||
}
|
||||
if err := proc.Kill(); err != nil {
|
||||
return fmt.Errorf("failed killing process: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue