mirror of https://github.com/docker/cli.git
Merge pull request #510 from dnephin/add-parse-log-details
Use a local copy of ParseLogDetails
This commit is contained in:
commit
aae519d0f6
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/idresolver"
|
"github.com/docker/cli/cli/command/idresolver"
|
||||||
|
"github.com/docker/cli/service/logs"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
|
@ -257,7 +258,7 @@ func (lw *logWriter) Write(buf []byte) (int, error) {
|
||||||
return 0, errors.Errorf("invalid context in log message: %v", string(buf))
|
return 0, errors.Errorf("invalid context in log message: %v", string(buf))
|
||||||
}
|
}
|
||||||
// parse the details out
|
// parse the details out
|
||||||
details, err := client.ParseLogDetails(string(parts[detailsIndex]))
|
details, err := logs.ParseLogDetails(string(parts[detailsIndex]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*Package logs contains tools for parsing docker log lines.
|
||||||
|
*/
|
||||||
|
package logs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ParseLogDetails parses a string of key value pairs in the form
|
||||||
|
// "k=v,l=w", where the keys and values are url query escaped, and each pair
|
||||||
|
// is separated by a comma. Returns a map of the key value pairs on success,
|
||||||
|
// and an error if the details string is not in a valid format.
|
||||||
|
//
|
||||||
|
// The details string encoding is implemented in
|
||||||
|
// github.com/moby/moby/api/server/httputils/write_log_stream.go
|
||||||
|
func ParseLogDetails(details string) (map[string]string, error) {
|
||||||
|
pairs := strings.Split(details, ",")
|
||||||
|
detailsMap := make(map[string]string, len(pairs))
|
||||||
|
for _, pair := range pairs {
|
||||||
|
p := strings.SplitN(pair, "=", 2)
|
||||||
|
// if there is no equals sign, we will only get 1 part back
|
||||||
|
if len(p) != 2 {
|
||||||
|
return nil, errors.New("invalid details format")
|
||||||
|
}
|
||||||
|
k, err := url.QueryUnescape(p[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
v, err := url.QueryUnescape(p[1])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
detailsMap[k] = v
|
||||||
|
}
|
||||||
|
return detailsMap, nil
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package logs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseLogDetails(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
line string
|
||||||
|
expected map[string]string
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
{"key=value", map[string]string{"key": "value"}, nil},
|
||||||
|
{"key1=value1,key2=value2", map[string]string{"key1": "value1", "key2": "value2"}, nil},
|
||||||
|
{"key+with+spaces=value%3Dequals,asdf%2C=", map[string]string{"key with spaces": "value=equals", "asdf,": ""}, nil},
|
||||||
|
{"key=,=nothing", map[string]string{"key": "", "": "nothing"}, nil},
|
||||||
|
{"=", map[string]string{"": ""}, nil},
|
||||||
|
{"errors", nil, errors.New("invalid details format")},
|
||||||
|
}
|
||||||
|
for _, testcase := range testCases {
|
||||||
|
t.Run(testcase.line, func(t *testing.T) {
|
||||||
|
actual, err := ParseLogDetails(testcase.line)
|
||||||
|
if testcase.err != nil {
|
||||||
|
assert.EqualError(t, err, testcase.err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert.Equal(t, testcase.expected, actual)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue