Skip to content

Commit

Permalink
fix: add timeout for command execution (#3980)
Browse files Browse the repository at this point in the history
  • Loading branch information
fengxsong committed Sep 25, 2023
1 parent b85926f commit 5b3b444
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 5 deletions.
4 changes: 3 additions & 1 deletion pkg/exec/exec.go
Expand Up @@ -84,7 +84,9 @@ func (w *wrap) CmdAsyncWithContext(ctx context.Context, host string, commands ..
}

func (w *wrap) CmdAsync(host string, commands ...string) error {
return w.CmdAsyncWithContext(context.Background(), host, commands...)
ctx, cancel := ssh.GetTimeoutContext()
defer cancel()
return w.CmdAsyncWithContext(ctx, host, commands...)
}

func warnIfNotAbs(path string) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/ssh/option.go
Expand Up @@ -46,7 +46,7 @@ func (o *Option) BindFlags(fs *pflag.FlagSet) {
fs.StringVarP(&o.privateKey, "private-key", "i", o.privateKey,
"selects a file from which the identity (private key) for public key authentication is read")
fs.StringVar(&o.passphrase, "passphrase", o.passphrase, "passphrase for decrypting a PEM encoded private key")
fs.DurationVar(&o.timeout, "timeout", o.timeout, "ssh connection timeout")
fs.DurationVar(&o.timeout, "timeout", o.timeout, "ssh connection establish timeout")
}

const (
Expand Down
14 changes: 13 additions & 1 deletion pkg/ssh/ssh.go
Expand Up @@ -16,6 +16,7 @@ package ssh

import (
"context"
"time"

"github.com/spf13/pflag"
"golang.org/x/crypto/ssh"
Expand All @@ -26,10 +27,21 @@ import (
"github.com/labring/sealos/pkg/utils/logger"
)

var defaultMaxRetry = 5
var (
defaultMaxRetry = 5
defaultExecutionTimeout = 300 * time.Second
)

func RegisterFlags(fs *pflag.FlagSet) {
fs.IntVar(&defaultMaxRetry, "max-retry", defaultMaxRetry, "define max num of ssh retry times")
fs.DurationVar(&defaultExecutionTimeout, "execution-timeout", defaultExecutionTimeout, "timeout setting of command execution")
}

// GetTimeoutContext create a context.Context with default timeout
// default execution timeout in sealos is just fine, if you want to customize the timeout setting,
// you must invoke the `RegisterFlags` function above.
func GetTimeoutContext() (context.Context, context.CancelFunc) {
return context.WithTimeout(context.Background(), defaultExecutionTimeout)
}

type Interface interface {
Expand Down
6 changes: 4 additions & 2 deletions pkg/ssh/sshcmd.go
Expand Up @@ -91,15 +91,17 @@ func (c *Client) CmdAsyncWithContext(ctx context.Context, host string, cmds ...s
}()
select {
case <-ctx.Done():
return nil
return ctx.Err()
case err = <-errCh:
return err
}
}

// CmdAsync not actually asynchronously, just print output asynchronously
func (c *Client) CmdAsync(host string, cmds ...string) error {
return c.CmdAsyncWithContext(context.Background(), host, cmds...)
ctx, cancel := GetTimeoutContext()
defer cancel()
return c.CmdAsyncWithContext(ctx, host, cmds...)
}

func (c *Client) Cmd(host, cmd string) ([]byte, error) {
Expand Down

0 comments on commit 5b3b444

Please sign in to comment.