Merge pull request #2032 from fcrisciani/debug-client
Diagnostic client
This commit is contained in:
commit
2459e6fbd3
15 changed files with 614 additions and 148 deletions
|
@ -28,6 +28,7 @@ build-local:
|
|||
@mkdir -p "bin"
|
||||
go build -tags experimental -o "bin/dnet" ./cmd/dnet
|
||||
go build -o "bin/docker-proxy" ./cmd/proxy
|
||||
GOOS=linux go build -o "./cmd/diagnostic/diagnosticClient" ./cmd/diagnostic
|
||||
|
||||
clean:
|
||||
@echo "🐳 $@"
|
||||
|
|
|
@ -297,8 +297,8 @@ func (c *controller) agentInit(listenAddr, bindAddrOrInterface, advertiseAddr, d
|
|||
return err
|
||||
}
|
||||
|
||||
// Register the diagnose handlers
|
||||
c.DiagnoseServer.RegisterHandler(nDB, networkdb.NetDbPaths2Func)
|
||||
// Register the diagnostic handlers
|
||||
c.DiagnosticServer.RegisterHandler(nDB, networkdb.NetDbPaths2Func)
|
||||
|
||||
var cancelList []func()
|
||||
ch, cancel := nDB.Watch(libnetworkEPTable, "", "")
|
||||
|
|
4
libnetwork/cmd/diagnostic/Dockerfile.client
Normal file
4
libnetwork/cmd/diagnostic/Dockerfile.client
Normal file
|
@ -0,0 +1,4 @@
|
|||
FROM alpine
|
||||
RUN apk add --no-cache curl
|
||||
COPY diagnosticClient /usr/local/bin/diagnosticClient
|
||||
ENTRYPOINT ["/usr/local/bin/diagnosticClient"]
|
4
libnetwork/cmd/diagnostic/Dockerfile.dind
Normal file
4
libnetwork/cmd/diagnostic/Dockerfile.dind
Normal file
|
@ -0,0 +1,4 @@
|
|||
FROM docker:17.12-dind
|
||||
RUN apk add --no-cache curl
|
||||
COPY daemon.json /etc/docker/daemon.json
|
||||
COPY diagnosticClient /usr/local/bin/diagnosticClient
|
252
libnetwork/cmd/diagnostic/README.md
Normal file
252
libnetwork/cmd/diagnostic/README.md
Normal file
|
@ -0,0 +1,252 @@
|
|||
---
|
||||
description: Learn to use the built-in network debugger to debug overlay networking problems
|
||||
keywords: network, troubleshooting, debug
|
||||
title: Debug overlay or swarm networking issues
|
||||
---
|
||||
|
||||
**WARNING**
|
||||
This tool can change the internal state of the libnetwork API, be really mindful
|
||||
on its use and read carefully the following guide. Improper use of it will damage
|
||||
or permanently destroy the network configuration.
|
||||
|
||||
|
||||
Docker CE 17.12 and higher introduce a network debugging tool designed to help
|
||||
debug issues with overlay networks and swarm services running on Linux hosts.
|
||||
When enabled, a network diagnostic server listens on the specified port and
|
||||
provides diagnostic information. The network debugging tool should only be
|
||||
started to debug specific issues, and should not be left running all the time.
|
||||
|
||||
Information about networks is stored in the database, which can be examined using
|
||||
the API. Currently the database contains information about the overlay network
|
||||
as well as the service discovery data.
|
||||
|
||||
The Docker API exposes endpoints to query and control the network debugging
|
||||
tool. CLI integration is provided as a preview, but the implementation is not
|
||||
yet considered stable and commands and options may change without notice.
|
||||
|
||||
The tool is available into 2 forms:
|
||||
1) client only: dockereng/network-diagnostic:onlyclient
|
||||
2) docker in docker version: dockereng/network-diagnostic:17.12-dind
|
||||
The latter allows to use the tool with a cluster running an engine older than 17.12
|
||||
|
||||
## Enable the diagnostic server
|
||||
|
||||
The tool currently only works on Docker hosts running on Linux. To enable it on a node
|
||||
follow the step below.
|
||||
|
||||
1. Set the `network-diagnostic-port` to a port which is free on the Docker
|
||||
host, in the `/etc/docker/daemon.json` configuration file.
|
||||
|
||||
```json
|
||||
“network-diagnostic-port”: <port>
|
||||
```
|
||||
|
||||
2. Get the process ID (PID) of the `dockerd` process. It is the second field in
|
||||
the output, and is typically a number from 2 to 6 digits long.
|
||||
|
||||
```bash
|
||||
$ ps aux |grep dockerd | grep -v grep
|
||||
```
|
||||
|
||||
3. Reload the Docker configuration without restarting Docker, by sending the
|
||||
`HUP` signal to the PID you found in the previous step.
|
||||
|
||||
```bash
|
||||
kill -HUP <pid-of-dockerd>
|
||||
```
|
||||
|
||||
If systemd is used the command `systemctl reload docker` will be enough
|
||||
|
||||
|
||||
A message like the following will appear in the Docker host logs:
|
||||
|
||||
```none
|
||||
Starting the diagnostic server listening on <port> for commands
|
||||
```
|
||||
|
||||
## Disable the diagnostic tool
|
||||
|
||||
Repeat these steps for each node participating in the swarm.
|
||||
|
||||
1. Remove the `network-diagnostic-port` key from the `/etc/docker/daemon.json`
|
||||
configuration file.
|
||||
|
||||
2. Get the process ID (PID) of the `dockerd` process. It is the second field in
|
||||
the output, and is typically a number from 2 to 6 digits long.
|
||||
|
||||
```bash
|
||||
$ ps aux |grep dockerd | grep -v grep
|
||||
```
|
||||
|
||||
3. Reload the Docker configuration without restarting Docker, by sending the
|
||||
`HUP` signal to the PID you found in the previous step.
|
||||
|
||||
```bash
|
||||
kill -HUP <pid-of-dockerd>
|
||||
```
|
||||
|
||||
A message like the following will appear in the Docker host logs:
|
||||
|
||||
```none
|
||||
Disabling the diagnostic server
|
||||
```
|
||||
|
||||
## Access the diagnostic tool's API
|
||||
|
||||
The network diagnostic tool exposes its own RESTful API. To access the API,
|
||||
send a HTTP request to the port where the tool is listening. The following
|
||||
commands assume the tool is listening on port 2000.
|
||||
|
||||
Examples are not given for every endpoint.
|
||||
|
||||
### Get help
|
||||
|
||||
```bash
|
||||
$ curl localhost:2000/help
|
||||
|
||||
OK
|
||||
/updateentry
|
||||
/getentry
|
||||
/gettable
|
||||
/leavenetwork
|
||||
/createentry
|
||||
/help
|
||||
/clusterpeers
|
||||
/ready
|
||||
/joinnetwork
|
||||
/deleteentry
|
||||
/networkpeers
|
||||
/
|
||||
/join
|
||||
```
|
||||
|
||||
### Join or leave the network database cluster
|
||||
|
||||
```bash
|
||||
$ curl localhost:2000/join?members=ip1,ip2,...
|
||||
```
|
||||
|
||||
```bash
|
||||
$ curl localhost:2000/leave?members=ip1,ip2,...
|
||||
```
|
||||
|
||||
`ip1`, `ip2`, ... are the swarm node ips (usually one is enough)
|
||||
|
||||
### Join or leave a network
|
||||
|
||||
```bash
|
||||
$ curl localhost:2000/joinnetwork?nid=<network id>
|
||||
```
|
||||
|
||||
```bash
|
||||
$ curl localhost:2000/leavenetwork?nid=<network id>
|
||||
```
|
||||
|
||||
`network id` can be retrieved on the manager with `docker network ls --no-trunc` and has
|
||||
to be the full length identifier
|
||||
|
||||
### List cluster peers
|
||||
|
||||
```bash
|
||||
$ curl localhost:2000/clusterpeers
|
||||
```
|
||||
|
||||
### List nodes connected to a given network
|
||||
|
||||
```bash
|
||||
$ curl localhost:2000/networkpeers?nid=<network id>
|
||||
```
|
||||
`network id` can be retrieved on the manager with `docker network ls --no-trunc` and has
|
||||
to be the full length identifier
|
||||
|
||||
### Dump database tables
|
||||
|
||||
The tables are called `endpoint_table` and `overlay_peer_table`.
|
||||
The `overlay_peer_table` contains all the overlay forwarding information
|
||||
The `endpoint_table` contains all the service discovery information
|
||||
|
||||
```bash
|
||||
$ curl localhost:2000/gettable?nid=<network id>&tname=<table name>
|
||||
```
|
||||
|
||||
### Interact with a specific database table
|
||||
|
||||
The tables are called `endpoint_table` and `overlay_peer_table`.
|
||||
|
||||
```bash
|
||||
$ curl localhost:2000/<method>?nid=<network id>&tname=<table name>&key=<key>[&value=<value>]
|
||||
```
|
||||
|
||||
Note:
|
||||
operations on tables have node ownership, this means that are going to remain persistent till
|
||||
the node that inserted them is part of the cluster
|
||||
|
||||
## Access the diagnostic tool's CLI
|
||||
|
||||
The CLI is provided as a preview and is not yet stable. Commands or options may
|
||||
change at any time.
|
||||
|
||||
The CLI executable is called `diagnosticClient` and is made available using a
|
||||
standalone container.
|
||||
|
||||
`docker run --net host dockereng/network-diagnostic:onlyclient -v -net <full network id> -t sd`
|
||||
|
||||
The following flags are supported:
|
||||
|
||||
| Flag | Description |
|
||||
|---------------|-------------------------------------------------|
|
||||
| -t <string> | Table one of `sd` or `overlay`. |
|
||||
| -ip <string> | The IP address to query. Defaults to 127.0.0.1. |
|
||||
| -net <string> | The target network ID. |
|
||||
| -port <int> | The target port. (default port is 2000) |
|
||||
| -v | Enable verbose output. |
|
||||
|
||||
### Container version of the diagnostic tool
|
||||
|
||||
The CLI is provided as a container with a 17.12 engine that needs to run using privileged mode.
|
||||
*NOTE*
|
||||
Remember that table operations have ownership, so any `create entry` will be persistent till
|
||||
the diagnostic container is part of the swarm.
|
||||
|
||||
1. Make sure that the node where the diagnostic client will run is not part of the swarm, if so do `docker swarm leave -f`
|
||||
|
||||
2. To run the container, use a command like the following:
|
||||
|
||||
```bash
|
||||
$ docker container run --name net-diagnostic -d --privileged --network host dockereng/network-diagnostic:17.12-dind
|
||||
```
|
||||
|
||||
3. Connect to the container using `docker exec -it <container-ID> sh`,
|
||||
and start the server using the following command:
|
||||
|
||||
```bash
|
||||
$ kill -HUP 1
|
||||
```
|
||||
|
||||
4. Join the diagnostic container to the swarm, then run the diagnostic CLI within the container.
|
||||
|
||||
```bash
|
||||
$ ./diagnosticClient <flags>...
|
||||
```
|
||||
|
||||
4. When finished debugging, leave the swarm and stop the container.
|
||||
|
||||
### Examples
|
||||
|
||||
The following commands dump the service discovery table and verify node
|
||||
ownership.
|
||||
|
||||
*NOTE*
|
||||
Remember to use the full network ID, you can easily find that with `docker network ls --no-trunc`
|
||||
|
||||
**Service discovery and load balancer:**
|
||||
|
||||
```bash
|
||||
$ diagnostiClient -c sd -v -net n8a8ie6tb3wr2e260vxj8ncy4
|
||||
```
|
||||
|
||||
**Overlay network:**
|
||||
|
||||
```bash
|
||||
$ diagnostiClient -port 2001 -c overlay -v -net n8a8ie6tb3wr2e260vxj8ncy4
|
||||
```
|
4
libnetwork/cmd/diagnostic/daemon.json
Normal file
4
libnetwork/cmd/diagnostic/daemon.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"debug": true,
|
||||
"network-diagnostic-port": 2000
|
||||
}
|
191
libnetwork/cmd/diagnostic/main.go
Normal file
191
libnetwork/cmd/diagnostic/main.go
Normal file
|
@ -0,0 +1,191 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/libnetwork"
|
||||
"github.com/docker/libnetwork/diagnostic"
|
||||
"github.com/docker/libnetwork/drivers/overlay"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
readyPath = "http://%s:%d/ready"
|
||||
joinNetwork = "http://%s:%d/joinnetwork?nid=%s"
|
||||
leaveNetwork = "http://%s:%d/leavenetwork?nid=%s"
|
||||
clusterPeers = "http://%s:%d/clusterpeers?json"
|
||||
networkPeers = "http://%s:%d/networkpeers?nid=%s&json"
|
||||
dumpTable = "http://%s:%d/gettable?nid=%s&tname=%s&json"
|
||||
deleteEntry = "http://%s:%d/deleteentry?nid=%s&tname=%s&key=%s&json"
|
||||
)
|
||||
|
||||
func httpIsOk(body io.ReadCloser) {
|
||||
b, err := ioutil.ReadAll(body)
|
||||
if err != nil {
|
||||
logrus.Fatalf("Failed the body parse %s", err)
|
||||
}
|
||||
if !strings.Contains(string(b), "OK") {
|
||||
logrus.Fatalf("Server not ready %s", b)
|
||||
}
|
||||
body.Close()
|
||||
}
|
||||
|
||||
func main() {
|
||||
ipPtr := flag.String("ip", "127.0.0.1", "ip address")
|
||||
portPtr := flag.Int("port", 2000, "port")
|
||||
networkPtr := flag.String("net", "", "target network")
|
||||
tablePtr := flag.String("t", "", "table to process <sd/overlay>")
|
||||
remediatePtr := flag.Bool("r", false, "perform remediation deleting orphan entries")
|
||||
verbosePtr := flag.Bool("v", false, "verbose output")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if *verbosePtr {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
}
|
||||
|
||||
logrus.Infof("Connecting to %s:%d checking ready", *ipPtr, *portPtr)
|
||||
resp, err := http.Get(fmt.Sprintf(readyPath, *ipPtr, *portPtr))
|
||||
if err != nil {
|
||||
logrus.WithError(err).Fatalf("The connection failed")
|
||||
}
|
||||
httpIsOk(resp.Body)
|
||||
|
||||
clusterPeers := fetchNodePeers(*ipPtr, *portPtr, "")
|
||||
var networkPeers map[string]string
|
||||
var joinedNetwork bool
|
||||
if *networkPtr != "" {
|
||||
logrus.Infof("Joining the network:%s", *networkPtr)
|
||||
resp, err = http.Get(fmt.Sprintf(joinNetwork, *ipPtr, *portPtr, *networkPtr))
|
||||
if err != nil {
|
||||
logrus.WithError(err).Fatalf("Failed joining the network")
|
||||
}
|
||||
httpIsOk(resp.Body)
|
||||
networkPeers = fetchNodePeers(*ipPtr, *portPtr, *networkPtr)
|
||||
joinedNetwork = true
|
||||
}
|
||||
|
||||
switch *tablePtr {
|
||||
case "sd":
|
||||
fetchTable(*ipPtr, *portPtr, *networkPtr, "endpoint_table", clusterPeers, networkPeers, *remediatePtr)
|
||||
case "overlay":
|
||||
fetchTable(*ipPtr, *portPtr, *networkPtr, "overlay_peer_table", clusterPeers, networkPeers, *remediatePtr)
|
||||
}
|
||||
|
||||
if joinedNetwork {
|
||||
resp, err = http.Get(fmt.Sprintf(leaveNetwork, *ipPtr, *portPtr, *networkPtr))
|
||||
if err != nil {
|
||||
logrus.WithError(err).Fatalf("Failed leaving the network")
|
||||
}
|
||||
httpIsOk(resp.Body)
|
||||
}
|
||||
}
|
||||
|
||||
func fetchNodePeers(ip string, port int, network string) map[string]string {
|
||||
logrus.Infof("Fetch peers %s", network)
|
||||
var path string
|
||||
if network != "" {
|
||||
path = fmt.Sprintf(networkPeers, ip, port, network)
|
||||
} else {
|
||||
path = fmt.Sprintf(clusterPeers, ip, port)
|
||||
}
|
||||
|
||||
resp, err := http.Get(path)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Fatalf("Failed fetching path")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Fatalf("Failed the body parse")
|
||||
}
|
||||
|
||||
output := diagnostic.HTTPResult{Details: &diagnostic.TablePeersResult{}}
|
||||
err = json.Unmarshal(body, &output)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Fatalf("Failed the json unmarshalling")
|
||||
}
|
||||
|
||||
logrus.Debugf("Parsing JSON response")
|
||||
result := make(map[string]string, output.Details.(*diagnostic.TablePeersResult).Length)
|
||||
for _, v := range output.Details.(*diagnostic.TablePeersResult).Elements {
|
||||
logrus.Debugf("name:%s ip:%s", v.Name, v.IP)
|
||||
result[v.Name] = v.IP
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func fetchTable(ip string, port int, network, tableName string, clusterPeers, networkPeers map[string]string, remediate bool) {
|
||||
logrus.Infof("Fetch %s table and check owners", tableName)
|
||||
resp, err := http.Get(fmt.Sprintf(dumpTable, ip, port, network, tableName))
|
||||
if err != nil {
|
||||
logrus.WithError(err).Fatalf("Failed fetching endpoint table")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Fatalf("Failed the body parse")
|
||||
}
|
||||
|
||||
output := diagnostic.HTTPResult{Details: &diagnostic.TableEndpointsResult{}}
|
||||
err = json.Unmarshal(body, &output)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Fatalf("Failed the json unmarshalling")
|
||||
}
|
||||
|
||||
logrus.Debug("Parsing data structures")
|
||||
var orphanKeys []string
|
||||
for _, v := range output.Details.(*diagnostic.TableEndpointsResult).Elements {
|
||||
decoded, err := base64.StdEncoding.DecodeString(v.Value)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("Failed decoding entry")
|
||||
continue
|
||||
}
|
||||
switch tableName {
|
||||
case "endpoint_table":
|
||||
var elem libnetwork.EndpointRecord
|
||||
elem.Unmarshal(decoded)
|
||||
logrus.Debugf("key:%s value:%+v owner:%s", v.Key, elem, v.Owner)
|
||||
case "overlay_peer_table":
|
||||
var elem overlay.PeerRecord
|
||||
elem.Unmarshal(decoded)
|
||||
logrus.Debugf("key:%s value:%+v owner:%s", v.Key, elem, v.Owner)
|
||||
}
|
||||
|
||||
if _, ok := networkPeers[v.Owner]; !ok {
|
||||
logrus.Warnf("The element with key:%s does not belong to any node on this network", v.Key)
|
||||
orphanKeys = append(orphanKeys, v.Key)
|
||||
}
|
||||
if _, ok := clusterPeers[v.Owner]; !ok {
|
||||
logrus.Warnf("The element with key:%s does not belong to any node on this cluster", v.Key)
|
||||
}
|
||||
}
|
||||
|
||||
if len(orphanKeys) > 0 && remediate {
|
||||
logrus.Warnf("The following keys:%v results as orphan, do you want to proceed with the deletion (this operation is irreversible)? [Yes/No]", orphanKeys)
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
text, _ := reader.ReadString('\n')
|
||||
text = strings.Replace(text, "\n", "", -1)
|
||||
if strings.Compare(text, "Yes") == 0 {
|
||||
for _, k := range orphanKeys {
|
||||
resp, err := http.Get(fmt.Sprintf(deleteEntry, ip, port, network, tableName, k))
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("Failed deleting entry k:%s", k)
|
||||
break
|
||||
}
|
||||
resp.Body.Close()
|
||||
}
|
||||
} else {
|
||||
logrus.Infof("Deletion skipped")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,7 +61,7 @@ import (
|
|||
"github.com/docker/libnetwork/cluster"
|
||||
"github.com/docker/libnetwork/config"
|
||||
"github.com/docker/libnetwork/datastore"
|
||||
"github.com/docker/libnetwork/diagnose"
|
||||
"github.com/docker/libnetwork/diagnostic"
|
||||
"github.com/docker/libnetwork/discoverapi"
|
||||
"github.com/docker/libnetwork/driverapi"
|
||||
"github.com/docker/libnetwork/drvregistry"
|
||||
|
@ -136,12 +136,12 @@ type NetworkController interface {
|
|||
// SetKeys configures the encryption key for gossip and overlay data path
|
||||
SetKeys(keys []*types.EncryptionKey) error
|
||||
|
||||
// StartDiagnose start the network diagnose mode
|
||||
StartDiagnose(port int)
|
||||
// StopDiagnose start the network diagnose mode
|
||||
StopDiagnose()
|
||||
// IsDiagnoseEnabled returns true if the diagnose is enabled
|
||||
IsDiagnoseEnabled() bool
|
||||
// StartDiagnostic start the network diagnostic mode
|
||||
StartDiagnostic(port int)
|
||||
// StopDiagnostic start the network diagnostic mode
|
||||
StopDiagnostic()
|
||||
// IsDiagnosticEnabled returns true if the diagnostic is enabled
|
||||
IsDiagnosticEnabled() bool
|
||||
}
|
||||
|
||||
// NetworkWalker is a client provided function which will be used to walk the Networks.
|
||||
|
@ -176,7 +176,7 @@ type controller struct {
|
|||
agentStopDone chan struct{}
|
||||
keys []*types.EncryptionKey
|
||||
clusterConfigAvailable bool
|
||||
DiagnoseServer *diagnose.Server
|
||||
DiagnosticServer *diagnostic.Server
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
|
@ -188,16 +188,16 @@ type initializer struct {
|
|||
// New creates a new instance of network controller.
|
||||
func New(cfgOptions ...config.Option) (NetworkController, error) {
|
||||
c := &controller{
|
||||
id: stringid.GenerateRandomID(),
|
||||
cfg: config.ParseConfigOptions(cfgOptions...),
|
||||
sandboxes: sandboxTable{},
|
||||
svcRecords: make(map[string]svcInfo),
|
||||
serviceBindings: make(map[serviceKey]*service),
|
||||
agentInitDone: make(chan struct{}),
|
||||
networkLocker: locker.New(),
|
||||
DiagnoseServer: diagnose.New(),
|
||||
id: stringid.GenerateRandomID(),
|
||||
cfg: config.ParseConfigOptions(cfgOptions...),
|
||||
sandboxes: sandboxTable{},
|
||||
svcRecords: make(map[string]svcInfo),
|
||||
serviceBindings: make(map[serviceKey]*service),
|
||||
agentInitDone: make(chan struct{}),
|
||||
networkLocker: locker.New(),
|
||||
DiagnosticServer: diagnostic.New(),
|
||||
}
|
||||
c.DiagnoseServer.Init()
|
||||
c.DiagnosticServer.Init()
|
||||
|
||||
if err := c.initStores(); err != nil {
|
||||
return nil, err
|
||||
|
@ -1307,27 +1307,27 @@ func (c *controller) Stop() {
|
|||
osl.GC()
|
||||
}
|
||||
|
||||
// StartDiagnose start the network diagnose mode
|
||||
func (c *controller) StartDiagnose(port int) {
|
||||
// StartDiagnostic start the network dias mode
|
||||
func (c *controller) StartDiagnostic(port int) {
|
||||
c.Lock()
|
||||
if !c.DiagnoseServer.IsDebugEnable() {
|
||||
c.DiagnoseServer.EnableDebug("127.0.0.1", port)
|
||||
if !c.DiagnosticServer.IsDiagnosticEnabled() {
|
||||
c.DiagnosticServer.EnableDiagnostic("127.0.0.1", port)
|
||||
}
|
||||
c.Unlock()
|
||||
}
|
||||
|
||||
// StopDiagnose start the network diagnose mode
|
||||
func (c *controller) StopDiagnose() {
|
||||
// StopDiagnostic start the network dias mode
|
||||
func (c *controller) StopDiagnostic() {
|
||||
c.Lock()
|
||||
if c.DiagnoseServer.IsDebugEnable() {
|
||||
c.DiagnoseServer.DisableDebug()
|
||||
if c.DiagnosticServer.IsDiagnosticEnabled() {
|
||||
c.DiagnosticServer.DisableDiagnostic()
|
||||
}
|
||||
c.Unlock()
|
||||
}
|
||||
|
||||
// IsDiagnoseEnabled returns true if the diagnose is enabled
|
||||
func (c *controller) IsDiagnoseEnabled() bool {
|
||||
// IsDiagnosticEnabled returns true if the dias is enabled
|
||||
func (c *controller) IsDiagnosticEnabled() bool {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
return c.DiagnoseServer.IsDebugEnable()
|
||||
return c.DiagnosticServer.IsDiagnosticEnabled()
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package diagnose
|
||||
package diagnostic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -44,7 +44,7 @@ type Server struct {
|
|||
sync.Mutex
|
||||
}
|
||||
|
||||
// New creates a new diagnose server
|
||||
// New creates a new diagnostic server
|
||||
func New() *Server {
|
||||
return &Server{
|
||||
registeredHanders: make(map[string]bool),
|
||||
|
@ -78,8 +78,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
s.mux.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// EnableDebug opens a TCP socket to debug the passed network DB
|
||||
func (s *Server) EnableDebug(ip string, port int) {
|
||||
// EnableDiagnostic opens a TCP socket to debug the passed network DB
|
||||
func (s *Server) EnableDiagnostic(ip string, port int) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
|
@ -90,7 +90,7 @@ func (s *Server) EnableDebug(ip string, port int) {
|
|||
return
|
||||
}
|
||||
|
||||
logrus.Infof("Starting the diagnose server listening on %d for commands", port)
|
||||
logrus.Infof("Starting the diagnostic server listening on %d for commands", port)
|
||||
srv := &http.Server{Addr: fmt.Sprintf("%s:%d", ip, port), Handler: s}
|
||||
s.srv = srv
|
||||
s.enable = 1
|
||||
|
@ -103,19 +103,19 @@ func (s *Server) EnableDebug(ip string, port int) {
|
|||
}(s)
|
||||
}
|
||||
|
||||
// DisableDebug stop the dubug and closes the tcp socket
|
||||
func (s *Server) DisableDebug() {
|
||||
// DisableDiagnostic stop the dubug and closes the tcp socket
|
||||
func (s *Server) DisableDiagnostic() {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
s.srv.Shutdown(context.Background())
|
||||
s.srv = nil
|
||||
s.enable = 0
|
||||
logrus.Info("Disabling the diagnose server")
|
||||
logrus.Info("Disabling the diagnostic server")
|
||||
}
|
||||
|
||||
// IsDebugEnable returns true when the debug is enabled
|
||||
func (s *Server) IsDebugEnable() bool {
|
||||
// IsDiagnosticEnabled returns true when the debug is enabled
|
||||
func (s *Server) IsDiagnosticEnabled() bool {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
return s.enable == 1
|
||||
|
@ -127,7 +127,7 @@ func notImplemented(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
rsp := WrongCommand("not implemented", fmt.Sprintf("URL path: %s no method implemented check /help\n", r.URL.Path))
|
||||
|
||||
// audit logs
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log.Info("command not implemented done")
|
||||
|
||||
HTTPReply(w, rsp, json)
|
||||
|
@ -138,7 +138,7 @@ func help(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
_, json := ParseHTTPFormOptions(r)
|
||||
|
||||
// audit logs
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log.Info("help done")
|
||||
|
||||
n, ok := ctx.(*Server)
|
||||
|
@ -156,7 +156,7 @@ func ready(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
_, json := ParseHTTPFormOptions(r)
|
||||
|
||||
// audit logs
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log.Info("ready done")
|
||||
HTTPReply(w, CommandSucceed(&StringCmd{Info: "OK"}), json)
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ func stackTrace(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
_, json := ParseHTTPFormOptions(r)
|
||||
|
||||
// audit logs
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log.Info("stack trace")
|
||||
|
||||
path, err := stackdump.DumpStacks("/tmp/")
|
|
@ -1,4 +1,4 @@
|
|||
package diagnose
|
||||
package diagnostic
|
||||
|
||||
import "fmt"
|
||||
|
||||
|
@ -31,7 +31,7 @@ func WrongCommand(message, usage string) *HTTPResult {
|
|||
}
|
||||
}
|
||||
|
||||
// HTTPResult Diagnose Server HTTP result operation
|
||||
// HTTPResult Diagnostic Server HTTP result operation
|
||||
type HTTPResult struct {
|
||||
Message string `json:"message"`
|
||||
Details StringInterface `json:"details"`
|
|
@ -328,6 +328,9 @@ func (nDB *NetworkDB) GetEntry(tname, nid, key string) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if entry != nil && entry.deleting {
|
||||
return nil, types.NotFoundErrorf("entry in table %s network id %s and key %s deleted and pending garbage collection", tname, nid, key)
|
||||
}
|
||||
|
||||
return entry.value, nil
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -446,6 +447,12 @@ func TestNetworkDBCRUDMediumCluster(t *testing.T) {
|
|||
dbs[i].verifyEntryExistence(t, "test_table", "network1", "test_key", "", false)
|
||||
}
|
||||
|
||||
for i := 1; i < n; i++ {
|
||||
_, err = dbs[i].GetEntry("test_table", "network1", "test_key")
|
||||
assert.Error(t, err)
|
||||
assert.True(t, strings.Contains(err.Error(), "deleted and pending garbage collection"))
|
||||
}
|
||||
|
||||
closeNetworkDBInstances(dbs)
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/docker/libnetwork/common"
|
||||
"github.com/docker/libnetwork/diagnose"
|
||||
"github.com/docker/libnetwork/diagnostic"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@ -17,7 +17,7 @@ const (
|
|||
)
|
||||
|
||||
// NetDbPaths2Func TODO
|
||||
var NetDbPaths2Func = map[string]diagnose.HTTPHandlerFunc{
|
||||
var NetDbPaths2Func = map[string]diagnostic.HTTPHandlerFunc{
|
||||
"/join": dbJoin,
|
||||
"/networkpeers": dbPeers,
|
||||
"/clusterpeers": dbClusterPeers,
|
||||
|
@ -32,17 +32,17 @@ var NetDbPaths2Func = map[string]diagnose.HTTPHandlerFunc{
|
|||
|
||||
func dbJoin(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
diagnose.DebugHTTPForm(r)
|
||||
_, json := diagnose.ParseHTTPFormOptions(r)
|
||||
diagnostic.DebugHTTPForm(r)
|
||||
_, json := diagnostic.ParseHTTPFormOptions(r)
|
||||
|
||||
// audit logs
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log.Info("join cluster")
|
||||
|
||||
if len(r.Form["members"]) < 1 {
|
||||
rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?members=ip1,ip2,...", r.URL.Path))
|
||||
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?members=ip1,ip2,...", r.URL.Path))
|
||||
log.Error("join cluster failed, wrong input")
|
||||
diagnose.HTTPReply(w, rsp, json)
|
||||
diagnostic.HTTPReply(w, rsp, json)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -50,88 +50,88 @@ func dbJoin(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
if ok {
|
||||
err := nDB.Join(strings.Split(r.Form["members"][0], ","))
|
||||
if err != nil {
|
||||
rsp := diagnose.FailCommand(fmt.Errorf("%s error in the DB join %s", r.URL.Path, err))
|
||||
rsp := diagnostic.FailCommand(fmt.Errorf("%s error in the DB join %s", r.URL.Path, err))
|
||||
log.WithError(err).Error("join cluster failed")
|
||||
diagnose.HTTPReply(w, rsp, json)
|
||||
diagnostic.HTTPReply(w, rsp, json)
|
||||
return
|
||||
}
|
||||
|
||||
log.Info("join cluster done")
|
||||
diagnose.HTTPReply(w, diagnose.CommandSucceed(nil), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json)
|
||||
return
|
||||
}
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
}
|
||||
|
||||
func dbPeers(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
diagnose.DebugHTTPForm(r)
|
||||
_, json := diagnose.ParseHTTPFormOptions(r)
|
||||
diagnostic.DebugHTTPForm(r)
|
||||
_, json := diagnostic.ParseHTTPFormOptions(r)
|
||||
|
||||
// audit logs
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log.Info("network peers")
|
||||
|
||||
if len(r.Form["nid"]) < 1 {
|
||||
rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=test", r.URL.Path))
|
||||
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=test", r.URL.Path))
|
||||
log.Error("network peers failed, wrong input")
|
||||
diagnose.HTTPReply(w, rsp, json)
|
||||
diagnostic.HTTPReply(w, rsp, json)
|
||||
return
|
||||
}
|
||||
|
||||
nDB, ok := ctx.(*NetworkDB)
|
||||
if ok {
|
||||
peers := nDB.Peers(r.Form["nid"][0])
|
||||
rsp := &diagnose.TableObj{Length: len(peers)}
|
||||
rsp := &diagnostic.TableObj{Length: len(peers)}
|
||||
for i, peerInfo := range peers {
|
||||
rsp.Elements = append(rsp.Elements, &diagnose.PeerEntryObj{Index: i, Name: peerInfo.Name, IP: peerInfo.IP})
|
||||
rsp.Elements = append(rsp.Elements, &diagnostic.PeerEntryObj{Index: i, Name: peerInfo.Name, IP: peerInfo.IP})
|
||||
}
|
||||
log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("network peers done")
|
||||
diagnose.HTTPReply(w, diagnose.CommandSucceed(rsp), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(rsp), json)
|
||||
return
|
||||
}
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
}
|
||||
|
||||
func dbClusterPeers(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
diagnose.DebugHTTPForm(r)
|
||||
_, json := diagnose.ParseHTTPFormOptions(r)
|
||||
diagnostic.DebugHTTPForm(r)
|
||||
_, json := diagnostic.ParseHTTPFormOptions(r)
|
||||
|
||||
// audit logs
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log.Info("cluster peers")
|
||||
|
||||
nDB, ok := ctx.(*NetworkDB)
|
||||
if ok {
|
||||
peers := nDB.ClusterPeers()
|
||||
rsp := &diagnose.TableObj{Length: len(peers)}
|
||||
rsp := &diagnostic.TableObj{Length: len(peers)}
|
||||
for i, peerInfo := range peers {
|
||||
rsp.Elements = append(rsp.Elements, &diagnose.PeerEntryObj{Index: i, Name: peerInfo.Name, IP: peerInfo.IP})
|
||||
rsp.Elements = append(rsp.Elements, &diagnostic.PeerEntryObj{Index: i, Name: peerInfo.Name, IP: peerInfo.IP})
|
||||
}
|
||||
log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("cluster peers done")
|
||||
diagnose.HTTPReply(w, diagnose.CommandSucceed(rsp), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(rsp), json)
|
||||
return
|
||||
}
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
}
|
||||
|
||||
func dbCreateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
diagnose.DebugHTTPForm(r)
|
||||
unsafe, json := diagnose.ParseHTTPFormOptions(r)
|
||||
diagnostic.DebugHTTPForm(r)
|
||||
unsafe, json := diagnostic.ParseHTTPFormOptions(r)
|
||||
|
||||
// audit logs
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log.Info("create entry")
|
||||
|
||||
if len(r.Form["tname"]) < 1 ||
|
||||
len(r.Form["nid"]) < 1 ||
|
||||
len(r.Form["key"]) < 1 ||
|
||||
len(r.Form["value"]) < 1 {
|
||||
rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k&value=v", r.URL.Path))
|
||||
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k&value=v", r.URL.Path))
|
||||
log.Error("create entry failed, wrong input")
|
||||
diagnose.HTTPReply(w, rsp, json)
|
||||
diagnostic.HTTPReply(w, rsp, json)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@ func dbCreateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
decodedValue, err = base64.StdEncoding.DecodeString(value)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("create entry failed")
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(err), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -153,34 +153,34 @@ func dbCreateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
nDB, ok := ctx.(*NetworkDB)
|
||||
if ok {
|
||||
if err := nDB.CreateEntry(tname, nid, key, decodedValue); err != nil {
|
||||
rsp := diagnose.FailCommand(err)
|
||||
diagnose.HTTPReply(w, rsp, json)
|
||||
rsp := diagnostic.FailCommand(err)
|
||||
diagnostic.HTTPReply(w, rsp, json)
|
||||
log.WithError(err).Error("create entry failed")
|
||||
return
|
||||
}
|
||||
log.Info("create entry done")
|
||||
diagnose.HTTPReply(w, diagnose.CommandSucceed(nil), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json)
|
||||
return
|
||||
}
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
}
|
||||
|
||||
func dbUpdateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
diagnose.DebugHTTPForm(r)
|
||||
unsafe, json := diagnose.ParseHTTPFormOptions(r)
|
||||
diagnostic.DebugHTTPForm(r)
|
||||
unsafe, json := diagnostic.ParseHTTPFormOptions(r)
|
||||
|
||||
// audit logs
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log.Info("update entry")
|
||||
|
||||
if len(r.Form["tname"]) < 1 ||
|
||||
len(r.Form["nid"]) < 1 ||
|
||||
len(r.Form["key"]) < 1 ||
|
||||
len(r.Form["value"]) < 1 {
|
||||
rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k&value=v", r.URL.Path))
|
||||
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k&value=v", r.URL.Path))
|
||||
log.Error("update entry failed, wrong input")
|
||||
diagnose.HTTPReply(w, rsp, json)
|
||||
diagnostic.HTTPReply(w, rsp, json)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ func dbUpdateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
decodedValue, err = base64.StdEncoding.DecodeString(value)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("update entry failed")
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(err), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -203,31 +203,31 @@ func dbUpdateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
if ok {
|
||||
if err := nDB.UpdateEntry(tname, nid, key, decodedValue); err != nil {
|
||||
log.WithError(err).Error("update entry failed")
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(err), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json)
|
||||
return
|
||||
}
|
||||
log.Info("update entry done")
|
||||
diagnose.HTTPReply(w, diagnose.CommandSucceed(nil), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json)
|
||||
return
|
||||
}
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
}
|
||||
|
||||
func dbDeleteEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
diagnose.DebugHTTPForm(r)
|
||||
_, json := diagnose.ParseHTTPFormOptions(r)
|
||||
diagnostic.DebugHTTPForm(r)
|
||||
_, json := diagnostic.ParseHTTPFormOptions(r)
|
||||
|
||||
// audit logs
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log.Info("delete entry")
|
||||
|
||||
if len(r.Form["tname"]) < 1 ||
|
||||
len(r.Form["nid"]) < 1 ||
|
||||
len(r.Form["key"]) < 1 {
|
||||
rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k", r.URL.Path))
|
||||
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k", r.URL.Path))
|
||||
log.Error("delete entry failed, wrong input")
|
||||
diagnose.HTTPReply(w, rsp, json)
|
||||
diagnostic.HTTPReply(w, rsp, json)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -240,31 +240,31 @@ func dbDeleteEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
err := nDB.DeleteEntry(tname, nid, key)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("delete entry failed")
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(err), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json)
|
||||
return
|
||||
}
|
||||
log.Info("delete entry done")
|
||||
diagnose.HTTPReply(w, diagnose.CommandSucceed(nil), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json)
|
||||
return
|
||||
}
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
}
|
||||
|
||||
func dbGetEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
diagnose.DebugHTTPForm(r)
|
||||
unsafe, json := diagnose.ParseHTTPFormOptions(r)
|
||||
diagnostic.DebugHTTPForm(r)
|
||||
unsafe, json := diagnostic.ParseHTTPFormOptions(r)
|
||||
|
||||
// audit logs
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log.Info("get entry")
|
||||
|
||||
if len(r.Form["tname"]) < 1 ||
|
||||
len(r.Form["nid"]) < 1 ||
|
||||
len(r.Form["key"]) < 1 {
|
||||
rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k", r.URL.Path))
|
||||
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k", r.URL.Path))
|
||||
log.Error("get entry failed, wrong input")
|
||||
diagnose.HTTPReply(w, rsp, json)
|
||||
diagnostic.HTTPReply(w, rsp, json)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -277,7 +277,7 @@ func dbGetEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
value, err := nDB.GetEntry(tname, nid, key)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("get entry failed")
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(err), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -288,27 +288,27 @@ func dbGetEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
encodedValue = base64.StdEncoding.EncodeToString(value)
|
||||
}
|
||||
|
||||
rsp := &diagnose.TableEntryObj{Key: key, Value: encodedValue}
|
||||
log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("update entry done")
|
||||
diagnose.HTTPReply(w, diagnose.CommandSucceed(rsp), json)
|
||||
rsp := &diagnostic.TableEntryObj{Key: key, Value: encodedValue}
|
||||
log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("get entry done")
|
||||
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(rsp), json)
|
||||
return
|
||||
}
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
}
|
||||
|
||||
func dbJoinNetwork(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
diagnose.DebugHTTPForm(r)
|
||||
_, json := diagnose.ParseHTTPFormOptions(r)
|
||||
diagnostic.DebugHTTPForm(r)
|
||||
_, json := diagnostic.ParseHTTPFormOptions(r)
|
||||
|
||||
// audit logs
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log.Info("join network")
|
||||
|
||||
if len(r.Form["nid"]) < 1 {
|
||||
rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=network_id", r.URL.Path))
|
||||
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=network_id", r.URL.Path))
|
||||
log.Error("join network failed, wrong input")
|
||||
diagnose.HTTPReply(w, rsp, json)
|
||||
diagnostic.HTTPReply(w, rsp, json)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -318,29 +318,29 @@ func dbJoinNetwork(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
if ok {
|
||||
if err := nDB.JoinNetwork(nid); err != nil {
|
||||
log.WithError(err).Error("join network failed")
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(err), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json)
|
||||
return
|
||||
}
|
||||
log.Info("join network done")
|
||||
diagnose.HTTPReply(w, diagnose.CommandSucceed(nil), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json)
|
||||
return
|
||||
}
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
}
|
||||
|
||||
func dbLeaveNetwork(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
diagnose.DebugHTTPForm(r)
|
||||
_, json := diagnose.ParseHTTPFormOptions(r)
|
||||
diagnostic.DebugHTTPForm(r)
|
||||
_, json := diagnostic.ParseHTTPFormOptions(r)
|
||||
|
||||
// audit logs
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log.Info("leave network")
|
||||
|
||||
if len(r.Form["nid"]) < 1 {
|
||||
rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=network_id", r.URL.Path))
|
||||
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=network_id", r.URL.Path))
|
||||
log.Error("leave network failed, wrong input")
|
||||
diagnose.HTTPReply(w, rsp, json)
|
||||
diagnostic.HTTPReply(w, rsp, json)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -350,30 +350,30 @@ func dbLeaveNetwork(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
if ok {
|
||||
if err := nDB.LeaveNetwork(nid); err != nil {
|
||||
log.WithError(err).Error("leave network failed")
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(err), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json)
|
||||
return
|
||||
}
|
||||
log.Info("leave network done")
|
||||
diagnose.HTTPReply(w, diagnose.CommandSucceed(nil), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json)
|
||||
return
|
||||
}
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
}
|
||||
|
||||
func dbGetTable(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
diagnose.DebugHTTPForm(r)
|
||||
unsafe, json := diagnose.ParseHTTPFormOptions(r)
|
||||
diagnostic.DebugHTTPForm(r)
|
||||
unsafe, json := diagnostic.ParseHTTPFormOptions(r)
|
||||
|
||||
// audit logs
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
||||
log.Info("get table")
|
||||
|
||||
if len(r.Form["tname"]) < 1 ||
|
||||
len(r.Form["nid"]) < 1 {
|
||||
rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id", r.URL.Path))
|
||||
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id", r.URL.Path))
|
||||
log.Error("get table failed, wrong input")
|
||||
diagnose.HTTPReply(w, rsp, json)
|
||||
diagnostic.HTTPReply(w, rsp, json)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -383,7 +383,7 @@ func dbGetTable(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
nDB, ok := ctx.(*NetworkDB)
|
||||
if ok {
|
||||
table := nDB.GetTableByNetwork(tname, nid)
|
||||
rsp := &diagnose.TableObj{Length: len(table)}
|
||||
rsp := &diagnostic.TableObj{Length: len(table)}
|
||||
var i = 0
|
||||
for k, v := range table {
|
||||
var encodedValue string
|
||||
|
@ -393,7 +393,7 @@ func dbGetTable(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
encodedValue = base64.StdEncoding.EncodeToString(v.Value)
|
||||
}
|
||||
rsp.Elements = append(rsp.Elements,
|
||||
&diagnose.TableEntryObj{
|
||||
&diagnostic.TableEntryObj{
|
||||
Index: i,
|
||||
Key: k,
|
||||
Value: encodedValue,
|
||||
|
@ -402,8 +402,8 @@ func dbGetTable(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
i++
|
||||
}
|
||||
log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("get table done")
|
||||
diagnose.HTTPReply(w, diagnose.CommandSucceed(rsp), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(rsp), json)
|
||||
return
|
||||
}
|
||||
diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
||||
}
|
|
@ -9,17 +9,17 @@ import (
|
|||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/docker/libnetwork/diagnose"
|
||||
"github.com/docker/libnetwork/diagnostic"
|
||||
"github.com/docker/libnetwork/networkdb"
|
||||
"github.com/docker/libnetwork/test/networkDb/dummyclient"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var nDB *networkdb.NetworkDB
|
||||
var server *diagnose.Server
|
||||
var server *diagnostic.Server
|
||||
var ipAddr string
|
||||
|
||||
var testerPaths2Func = map[string]diagnose.HTTPHandlerFunc{
|
||||
var testerPaths2Func = map[string]diagnostic.HTTPHandlerFunc{
|
||||
"/myip": ipaddress,
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ func Server(args []string) {
|
|||
ipAddr = ip
|
||||
logrus.Infof("%s uses IP %s\n", localNodeName, ipAddr)
|
||||
|
||||
server = diagnose.New()
|
||||
server = diagnostic.New()
|
||||
server.Init()
|
||||
conf := networkdb.DefaultConfig()
|
||||
conf.Hostname = localNodeName
|
||||
|
@ -65,7 +65,7 @@ func Server(args []string) {
|
|||
server.RegisterHandler(nDB, networkdb.NetDbPaths2Func)
|
||||
server.RegisterHandler(nil, testerPaths2Func)
|
||||
server.RegisterHandler(nDB, dummyclient.DummyClientPaths2Func)
|
||||
server.EnableDebug("", port)
|
||||
server.EnableDiagnostic("", port)
|
||||
// block here
|
||||
select {}
|
||||
}
|
||||
|
|
|
@ -6,13 +6,13 @@ import (
|
|||
"net/http"
|
||||
|
||||
events "github.com/docker/go-events"
|
||||
"github.com/docker/libnetwork/diagnose"
|
||||
"github.com/docker/libnetwork/diagnostic"
|
||||
"github.com/docker/libnetwork/networkdb"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// DummyClientPaths2Func exported paths for the client
|
||||
var DummyClientPaths2Func = map[string]diagnose.HTTPHandlerFunc{
|
||||
var DummyClientPaths2Func = map[string]diagnostic.HTTPHandlerFunc{
|
||||
"/watchtable": watchTable,
|
||||
"/watchedtableentries": watchTableEntries,
|
||||
}
|
||||
|
@ -30,10 +30,10 @@ var clientWatchTable = map[string]tableHandler{}
|
|||
|
||||
func watchTable(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
diagnose.DebugHTTPForm(r)
|
||||
diagnostic.DebugHTTPForm(r)
|
||||
if len(r.Form["tname"]) < 1 {
|
||||
rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name", r.URL.Path))
|
||||
diagnose.HTTPReply(w, rsp, &diagnose.JSONOutput{})
|
||||
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name", r.URL.Path))
|
||||
diagnostic.HTTPReply(w, rsp, &diagnostic.JSONOutput{})
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -55,10 +55,10 @@ func watchTable(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func watchTableEntries(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
diagnose.DebugHTTPForm(r)
|
||||
diagnostic.DebugHTTPForm(r)
|
||||
if len(r.Form["tname"]) < 1 {
|
||||
rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name", r.URL.Path))
|
||||
diagnose.HTTPReply(w, rsp, &diagnose.JSONOutput{})
|
||||
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name", r.URL.Path))
|
||||
diagnostic.HTTPReply(w, rsp, &diagnostic.JSONOutput{})
|
||||
return
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue