Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions platform/osInterface.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
package platform

type execClient struct{}
import (
"time"
)

const (
defaultExecTimeout = 10
)

type execClient struct {
Timeout time.Duration
}

//nolint:revive // ExecClient make sense
type ExecClient interface {
ExecuteCommand(command string) (string, error)
}

func NewExecClient() ExecClient {
return &execClient{}
return &execClient{
Timeout: defaultExecTimeout * time.Second,
}
}

func NewExecClientTimeout(timeout time.Duration) ExecClient {
return &execClient{
Timeout: timeout,
}
}
18 changes: 12 additions & 6 deletions platform/os_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package platform

import (
"bytes"
"context"
"fmt"
"os"
"os/exec"
Expand Down Expand Up @@ -50,7 +51,7 @@ func GetOSInfo() string {
}

func GetProcessSupport() error {
p := &execClient{}
p := NewExecClient()
cmd := fmt.Sprintf("ps -p %v -o comm=", os.Getpid())
_, err := p.ExecuteCommand(cmd)
return err
Expand Down Expand Up @@ -81,7 +82,12 @@ func (p *execClient) ExecuteCommand(command string) (string, error) {

var stderr bytes.Buffer
var out bytes.Buffer
cmd := exec.Command("sh", "-c", command)

// Create a new context and add a timeout to it
ctx, cancel := context.WithTimeout(context.Background(), p.Timeout)
defer cancel() // The cancel should be deferred so resources are cleaned up

cmd := exec.CommandContext(ctx, "sh", "-c", command)
cmd.Stderr = &stderr
cmd.Stdout = &out

Expand All @@ -94,7 +100,7 @@ func (p *execClient) ExecuteCommand(command string) (string, error) {
}

func SetOutboundSNAT(subnet string) error {
p := execClient{}
p := NewExecClient()
cmd := fmt.Sprintf("iptables -t nat -A POSTROUTING -m iprange ! --dst-range 168.63.129.16 -m addrtype ! --dst-type local ! -d %v -j MASQUERADE",
subnet)
_, err := p.ExecuteCommand(cmd)
Expand All @@ -112,7 +118,7 @@ func ClearNetworkConfiguration() (bool, error) {
}

func KillProcessByName(processName string) error {
p := &execClient{}
p := NewExecClient()
cmd := fmt.Sprintf("pkill -f %v", processName)
_, err := p.ExecuteCommand(cmd)
return err
Expand Down Expand Up @@ -143,7 +149,7 @@ func GetOSDetails() (map[string]string, error) {
}

func GetProcessNameByID(pidstr string) (string, error) {
p := &execClient{}
p := NewExecClient()
pidstr = strings.Trim(pidstr, "\n")
cmd := fmt.Sprintf("ps -p %s -o comm=", pidstr)
out, err := p.ExecuteCommand(cmd)
Expand All @@ -159,7 +165,7 @@ func GetProcessNameByID(pidstr string) (string, error) {
}

func PrintDependencyPackageDetails() {
p := &execClient{}
p := NewExecClient()
out, err := p.ExecuteCommand("iptables --version")
out = strings.TrimSuffix(out, "\n")
log.Printf("[cni-net] iptable version:%s, err:%v", out, err)
Expand Down
29 changes: 29 additions & 0 deletions platform/os_linux_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package platform

import (
"testing"
"time"
)

// Command execution time is more than timeout, so ExecuteCommand should return error
func TestExecuteCommandTimeout(t *testing.T) {
const timeout = 2 * time.Second
client := NewExecClientTimeout(timeout)

_, err := client.ExecuteCommand("sleep 3")
if err == nil {
t.Errorf("TestExecuteCommandTimeout should have returned timeout error")
}
t.Logf("%s", err.Error())
}

// Command execution time is less than timeout, so ExecuteCommand should work without error
func TestExecuteCommandNoTimeout(t *testing.T) {
const timeout = 2 * time.Second
client := NewExecClientTimeout(timeout)

_, err := client.ExecuteCommand("sleep 1")
if err != nil {
t.Errorf("TestExecuteCommandNoTimeout failed with error %v", err)
}
}