Updating executor to remove old util.go
Adding new Network interaction "class"
This commit is contained in:
parent
735bc8d19e
commit
b680e256b9
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Executor interface to describe command runners signature
|
// Executor interface to describe command runners signature
|
||||||
|
@ -12,12 +13,22 @@ type Executor interface {
|
||||||
Run(command string, params ...string) *CommandResult
|
Run(command string, params ...string) *CommandResult
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CommandResult contain all information about a command execution, stdout, stderr
|
||||||
|
type CommandResult struct {
|
||||||
|
Stdout string
|
||||||
|
Stderr string
|
||||||
|
ReturnCode int
|
||||||
|
}
|
||||||
|
|
||||||
type localExecutor struct{}
|
type localExecutor struct{}
|
||||||
|
|
||||||
func (e *localExecutor) Run(command string, params ...string) *CommandResult {
|
func (e *localExecutor) Run(command string, params ...string) *CommandResult {
|
||||||
|
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
var stderr bytes.Buffer
|
var stderr bytes.Buffer
|
||||||
|
var exitCode int
|
||||||
|
|
||||||
|
defaultFailedCode := 255
|
||||||
|
|
||||||
exe := exec.Command(command, params...)
|
exe := exec.Command(command, params...)
|
||||||
exe.Stdout = &out
|
exe.Stdout = &out
|
||||||
|
@ -25,14 +36,32 @@ func (e *localExecutor) Run(command string, params ...string) *CommandResult {
|
||||||
|
|
||||||
err := exe.Run()
|
err := exe.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if exitError, ok := err.(*exec.ExitError); ok {
|
||||||
|
ws := exitError.Sys().(syscall.WaitStatus)
|
||||||
|
exitCode = ws.ExitStatus()
|
||||||
|
} else {
|
||||||
|
// This will happen (in OSX) if `name` is not available in $PATH,
|
||||||
|
// in this situation, exit code could not be get, and stderr will be
|
||||||
|
// empty string very likely, so we use the default fail code, and format err
|
||||||
|
// to string and set to stderr
|
||||||
|
log.Printf("Could not get exit code for failed program: %v, %v", command, params)
|
||||||
|
exitCode = defaultFailedCode
|
||||||
|
}
|
||||||
fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
|
fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
// try to get the exit code
|
||||||
|
} else {
|
||||||
|
// success, exitCode should be 0 if go is ok
|
||||||
|
ws := exe.ProcessState.Sys().(syscall.WaitStatus)
|
||||||
|
exitCode = ws.ExitStatus()
|
||||||
|
}
|
||||||
|
|
||||||
return &CommandResult{
|
return &CommandResult{
|
||||||
Stdout: out.String(),
|
Stdout: out.String(),
|
||||||
Stderr: stderr.String(),
|
Stderr: stderr.String(),
|
||||||
// FIXME
|
ReturnCode: exitCode,
|
||||||
ReturnCode: 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package openwrt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRun(t *testing.T) {
|
||||||
|
exec := &localExecutor{}
|
||||||
|
res := exec.Run("uname", "-a")
|
||||||
|
if g, e := res.ReturnCode, 0; g != e {
|
||||||
|
t.Errorf("Run command failed ! Got bad return code [%d], [%d} is expected\n", g, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// res = exec.Run("noCommandWithThisNameExists", "-a")
|
||||||
|
// if g, e := res.ReturnCode, 127; g != e {
|
||||||
|
// t.Errorf("Run command failed ! Got bad return code [%d], [%d} is expected\n", g, e)
|
||||||
|
// }
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package openwrt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Network provides a representation of network
|
||||||
|
type Network struct {
|
||||||
|
exec Executor
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNetwork return an UCI instance to interact with UCI
|
||||||
|
func NewNetwork() *Network {
|
||||||
|
exec := &localExecutor{}
|
||||||
|
return &Network{exec}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNetworkWithExecutor return an UCI instance to interact with UCI
|
||||||
|
func NewNetworkWithExecutor(exe Executor) *Network {
|
||||||
|
exec := exe
|
||||||
|
return &Network{exec}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListInterfaces list all available interfaces on a system using "ip" commmand
|
||||||
|
func (n *Network) ListInterfaces() []net.Interface {
|
||||||
|
var result []net.Interface
|
||||||
|
ifaces, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Print(fmt.Errorf("error listing network interfacess: %+v", err.Error()))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, i := range ifaces {
|
||||||
|
result = append(result, i)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListWirelessInterfaces list all wifi cards
|
||||||
|
func (n *Network) ListWirelessInterfaces() []net.Interface {
|
||||||
|
var result []net.Interface
|
||||||
|
var ifaceNames []string
|
||||||
|
|
||||||
|
wifiFile := "/proc/net/wireless"
|
||||||
|
|
||||||
|
wifiFileContent, err := ioutil.ReadFile(wifiFile)
|
||||||
|
check(err)
|
||||||
|
|
||||||
|
index := 0
|
||||||
|
for _, line := range strings.Split(string(wifiFileContent), "\n") {
|
||||||
|
if index < 2 {
|
||||||
|
index++
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
name := strings.Split(line, ":")[0]
|
||||||
|
ifaceNames = append(ifaceNames, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ifaces, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Print(fmt.Errorf("error listing network interfaces : %+v", err.Error()))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, i := range ifaces {
|
||||||
|
for _, name := range ifaceNames {
|
||||||
|
if name == i.Name {
|
||||||
|
result = append(result, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package openwrt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNetworkListInterfaces(t *testing.T) {
|
||||||
|
net := NewNetwork()
|
||||||
|
iface := net.ListInterfaces()
|
||||||
|
for _, ife := range iface {
|
||||||
|
fmt.Printf("%s\n", ife.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListWirelessInterfaces(t *testing.T) {
|
||||||
|
net := NewNetwork()
|
||||||
|
res := net.ListWirelessInterfaces()
|
||||||
|
for _, el := range res {
|
||||||
|
fmt.Printf("%s\n", el.Name)
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,12 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func check(e error) {
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func createMockExecutor(stdout string, stderr string, returnCode int) Executor {
|
func createMockExecutor(stdout string, stderr string, returnCode int) Executor {
|
||||||
return &mockExecutor{
|
return &mockExecutor{
|
||||||
stdout: stdout,
|
stdout: stdout,
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
package openwrt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os/exec"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CommandResult contain all information about a command execution, stdout, stderr
|
|
||||||
type CommandResult struct {
|
|
||||||
Stdout string
|
|
||||||
Stderr string
|
|
||||||
ReturnCode int
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run executes a system command and returns
|
|
||||||
func run(command string, params ...string) *CommandResult {
|
|
||||||
var out bytes.Buffer
|
|
||||||
var stderr bytes.Buffer
|
|
||||||
|
|
||||||
exe := exec.Command(command, params...)
|
|
||||||
exe.Stdout = &out
|
|
||||||
exe.Stderr = &stderr
|
|
||||||
|
|
||||||
err := exe.Run()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &CommandResult{
|
|
||||||
Stdout: out.String(),
|
|
||||||
Stderr: stderr.String(),
|
|
||||||
// FIXME
|
|
||||||
ReturnCode: 0,
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue