Skip to content

Commit f19768d

Browse files
committed
Change key transfering method
fix debug test update debug merge func merge func update syntax update
1 parent 96c3bb3 commit f19768d

File tree

2 files changed

+184
-47
lines changed

2 files changed

+184
-47
lines changed

pkg/ckecli/cmd/scp.go

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package cmd
33
import (
44
"context"
55
"errors"
6-
"fmt"
76
"os"
87
"os/exec"
98
"strings"
@@ -28,19 +27,36 @@ func detectSCPNode(args []string) (string, error) {
2827
return nodeName, nil
2928
}
3029

31-
func scp(ctx context.Context, args []string) error {
30+
func scpSubMain(ctx context.Context, args []string) error {
31+
pipeFilename, err := createFifo2()
32+
if err != nil {
33+
return err
34+
}
35+
3236
node, err := detectSCPNode(args)
3337
if err != nil {
3438
return err
3539
}
36-
fifo, err := sshPrivateKey(node)
40+
41+
pirvateKey, err := getPrivateKey(node)
3742
if err != nil {
3843
return err
3944
}
40-
defer os.Remove(fifo)
45+
46+
go func() {
47+
if _, err := sshAgent(ctx, pipeFilename); err != nil {
48+
// ログ出力
49+
return
50+
}
51+
}()
52+
53+
if err = writeToFifo(pipeFilename, pirvateKey); err != nil {
54+
return err
55+
}
56+
defer os.Remove(pipeFilename)
57+
defer killSshAgent(ctx)
4158

4259
scpArgs := []string{
43-
"-i", fifo,
4460
"-o", "UserKnownHostsFile=/dev/null",
4561
"-o", "StrictHostKeyChecking=no",
4662
"-o", "ConnectTimeout=60",
@@ -50,14 +66,32 @@ func scp(ctx context.Context, args []string) error {
5066
}
5167

5268
scpArgs = append(scpArgs, args...)
69+
c := exec.CommandContext(ctx, "scp", scpArgs...)
70+
c.Stdin = os.Stdin
71+
c.Stdout = os.Stdout
72+
c.Stderr = os.Stderr
73+
return c.Run()
74+
}
75+
76+
/*
77+
func scp(ctx context.Context, args []string) error {
78+
scpArgs := []string{
79+
"-o", "UserKnownHostsFile=/dev/null",
80+
"-o", "StrictHostKeyChecking=no",
81+
"-o", "ConnectTimeout=60",
82+
}
83+
if scpParams.recursive {
84+
scpArgs = append(scpArgs, "-r")
85+
}
5386
54-
fmt.Println(scpArgs)
87+
scpArgs = append(scpArgs, args...)
5588
c := exec.CommandContext(ctx, "scp", scpArgs...)
5689
c.Stdin = os.Stdin
5790
c.Stdout = os.Stdout
5891
c.Stderr = os.Stderr
5992
return c.Run()
6093
}
94+
*/
6195

6296
var scpParams struct {
6397
recursive bool
@@ -75,7 +109,7 @@ NODE is IP address or hostname of the node.
75109
Args: cobra.MinimumNArgs(2),
76110
RunE: func(cmd *cobra.Command, args []string) error {
77111
well.Go(func(ctx context.Context) error {
78-
return scp(ctx, args)
112+
return scpSubMain(ctx, args)
79113
})
80114
well.Stop()
81115
return well.Wait()

pkg/ckecli/cmd/ssh.go

Lines changed: 143 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ package cmd
33
import (
44
"context"
55
"errors"
6+
"fmt"
67
"os"
78
"os/exec"
89
"os/user"
910
"path/filepath"
1011
"strconv"
1112
"strings"
1213
"syscall"
13-
"time"
1414

1515
"github.com/cybozu-go/cke"
1616
"github.com/cybozu-go/log"
@@ -26,51 +26,45 @@ func detectSSHNode(arg string) string {
2626
return nodeName
2727
}
2828

29-
func writeToFifo(fifo string, data string) {
30-
f, err := os.OpenFile(fifo, os.O_WRONLY, 0600)
29+
func createFifo2() (string, error) {
30+
usr, err := user.Current()
3131
if err != nil {
32-
log.Error("failed to open fifo", map[string]interface{}{
33-
log.FnError: err,
34-
"fifo": fifo,
35-
})
36-
return
32+
return "", err
3733
}
38-
defer f.Close()
3934

40-
_, err = f.WriteString(data)
41-
if err != nil {
42-
log.Error("failed to write to fifo", map[string]interface{}{
43-
log.FnError: err,
44-
"fifo": fifo,
45-
})
35+
fifoFilePath := filepath.Join(usr.HomeDir, ".ssh", "ckecli-ssh-key-"+strconv.Itoa(os.Getpid()))
36+
_, err = os.Stat(fifoFilePath)
37+
if os.IsExist(err) {
38+
return fifoFilePath, nil
4639
}
47-
}
48-
49-
func sshPrivateKey(nodeName string) (string, error) {
50-
usr, err := user.Current()
51-
if err != nil {
40+
if !os.IsNotExist(err) {
5241
return "", err
5342
}
43+
5444
err = os.MkdirAll(filepath.Join(usr.HomeDir, ".ssh"), 0700)
5545
if err != nil {
5646
return "", err
5747
}
58-
fifo := filepath.Join(usr.HomeDir, ".ssh", "ckecli-ssh-key-"+strconv.Itoa(os.Getpid()))
59-
err = syscall.Mkfifo(fifo, 0600)
48+
49+
err = syscall.Mkfifo(fifoFilePath, 0600)
6050
if err != nil {
6151
return "", err
6252
}
6353

54+
return fifoFilePath, err
55+
}
56+
57+
func getPrivateKey(nodeName string) ([]byte, error) {
6458
vc, err := inf.Vault()
6559
if err != nil {
66-
return "", err
60+
return nil, err
6761
}
6862
secret, err := vc.Logical().Read(cke.SSHSecret)
6963
if err != nil {
70-
return "", err
64+
return nil, err
7165
}
7266
if secret == nil {
73-
return "", errors.New("no ssh private keys")
67+
return nil, errors.New("no ssh private keys")
7468
}
7569
privKeys := secret.Data
7670

@@ -79,31 +73,124 @@ func sshPrivateKey(nodeName string) (string, error) {
7973
mykey = privKeys[""]
8074
}
8175
if mykey == nil {
82-
return "", errors.New("no ssh private key for " + nodeName)
76+
return nil, errors.New("no ssh private key for " + nodeName)
8377
}
78+
/*
79+
go func() {
80+
// OpenSSH reads the private key file three times, it need to write key three times.
81+
writeToFifo(fifo, mykey.(string))
82+
time.Sleep(100 * time.Millisecond)
83+
writeToFifo(fifo, mykey.(string))
84+
time.Sleep(100 * time.Millisecond)
85+
writeToFifo(fifo, mykey.(string))
86+
}()
87+
*/
88+
return mykey.([]byte), nil
89+
}
8490

85-
go func() {
86-
// OpenSSH reads the private key file three times, it need to write key three times.
87-
writeToFifo(fifo, mykey.(string))
88-
time.Sleep(100 * time.Millisecond)
89-
writeToFifo(fifo, mykey.(string))
90-
time.Sleep(100 * time.Millisecond)
91-
writeToFifo(fifo, mykey.(string))
92-
}()
91+
func sshAgent(ctx context.Context, privateKeyFile string) (map[string]string, error) {
92+
myEnv := make(map[string]string)
93+
94+
sshArgs := []string{
95+
"-s",
96+
}
97+
cmd := exec.CommandContext(ctx, "ssh-agent", sshArgs...)
98+
stdoutStderr, err := cmd.CombinedOutput()
99+
if err != nil {
100+
return nil, err
101+
}
102+
line := strings.Split(string(stdoutStderr), "\n")
103+
104+
partOfLine := strings.Split(line[0], ";")
105+
kvPair := strings.Split(partOfLine[0], "=")
106+
myEnv[kvPair[0]] = kvPair[1]
107+
err = os.Setenv(kvPair[0], kvPair[1])
108+
if err != nil {
109+
return nil, err
110+
}
93111

94-
return fifo, nil
112+
partOfLine = strings.Split(line[1], ";")
113+
kvPair = strings.Split(partOfLine[0], "=")
114+
myEnv[kvPair[0]] = kvPair[1]
115+
err = os.Setenv(kvPair[0], kvPair[1])
116+
if err != nil {
117+
return nil, err
118+
}
119+
120+
sshArgs2 := []string{
121+
privateKeyFile,
122+
}
123+
cmd0 := exec.CommandContext(ctx, "ssh-add", sshArgs2...)
124+
_, err = cmd0.CombinedOutput()
125+
if err != nil {
126+
return nil, err
127+
}
128+
129+
return myEnv, nil
95130
}
96131

97-
func ssh(ctx context.Context, args []string) error {
132+
func killSshAgent(ctx context.Context) error {
133+
sshArgs := []string{
134+
"-k",
135+
}
136+
cmd := exec.CommandContext(ctx, "ssh-agent", sshArgs...)
137+
stdoutStderr, err := cmd.CombinedOutput()
138+
if err != nil {
139+
fmt.Println("Error ssh-agent -k ", err)
140+
return err
141+
}
142+
fmt.Println("kill ssh agent :: output=", string(stdoutStderr))
143+
return nil
144+
}
145+
146+
func writeToFifo(fifo string, data []byte) error {
147+
f, err := os.OpenFile(fifo, os.O_WRONLY|os.O_CREATE|os.O_APPEND, os.ModeNamedPipe)
148+
if err != nil {
149+
log.Error("failed to open fifo", map[string]interface{}{
150+
log.FnError: err,
151+
"fifo": fifo,
152+
})
153+
return err
154+
}
155+
defer f.Close()
156+
if _, err = f.Write(data); err != nil {
157+
log.Error("failed to write to fifo", map[string]interface{}{
158+
log.FnError: err,
159+
"fifo": fifo,
160+
})
161+
return err
162+
}
163+
return nil
164+
}
165+
166+
func sshSubMain(ctx context.Context, args []string) error {
167+
pipeFilename, err := createFifo2()
168+
if err != nil {
169+
return err
170+
}
171+
98172
node := detectSSHNode(args[0])
99-
fifo, err := sshPrivateKey(node)
173+
pirvateKey, err := getPrivateKey(node)
100174
if err != nil {
101175
return err
102176
}
103-
defer os.Remove(fifo)
104177

178+
go func() {
179+
if _, err := sshAgent(ctx, pipeFilename); err != nil {
180+
fmt.Println("getPrivateKey err=", err, "node=", node)
181+
// ログ出力
182+
return
183+
}
184+
}()
185+
186+
if err = writeToFifo(pipeFilename, pirvateKey); err != nil {
187+
return err
188+
}
189+
defer os.Remove(pipeFilename)
190+
defer killSshAgent(ctx)
191+
192+
//return ssh(ctx, args)
105193
sshArgs := []string{
106-
"-i", fifo,
107194
"-o", "UserKnownHostsFile=/dev/null",
108195
"-o", "StrictHostKeyChecking=no",
109196
"-o", "ConnectTimeout=60",
@@ -116,6 +203,22 @@ func ssh(ctx context.Context, args []string) error {
116203
return c.Run()
117204
}
118205

206+
/*
207+
func ssh(ctx context.Context, args []string) (error, string) {
208+
sshArgs := []string{
209+
"-o", "UserKnownHostsFile=/dev/null",
210+
"-o", "StrictHostKeyChecking=no",
211+
"-o", "ConnectTimeout=60",
212+
}
213+
sshArgs = append(sshArgs, args...)
214+
c := exec.CommandContext(ctx, "ssh", sshArgs...)
215+
c.Stdin = os.Stdin
216+
c.Stdout = os.Stdout
217+
c.Stderr = os.Stderr
218+
return c.Run(), "OK"
219+
}
220+
*/
221+
119222
// sshCmd represents the ssh command
120223
var sshCmd = &cobra.Command{
121224
Use: "ssh [user@]NODE [COMMAND...]",
@@ -130,7 +233,7 @@ If COMMAND is specified, it will be executed on the node.
130233
Args: cobra.MinimumNArgs(1),
131234
RunE: func(cmd *cobra.Command, args []string) error {
132235
well.Go(func(ctx context.Context) error {
133-
return ssh(ctx, args)
236+
return sshSubMain(ctx, args)
134237
})
135238
well.Stop()
136239
return well.Wait()

0 commit comments

Comments
 (0)