mirror of
https://github.com/moby/moby.git
synced 2026-01-11 10:41:43 +00:00
api/types/jsonstream: define Message type
The schema of a JSON-stream message is very pertinent to the api module. Provide a canonical definition in the api module and refactor the daemon code to use it. Drop the long-deprecated ErrorMessage field from the API definition, but have the daemon continue to emit it for compatibility with docker-py v7.1.0. Co-authored-by: Cory Snider <csnider@mirantis.com> Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
This commit is contained in:
committed by
Austin Vazquez
parent
ae28867804
commit
687c3d7f42
15
api/types/jsonstream/message.go
Normal file
15
api/types/jsonstream/message.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package jsonstream
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// JSONMessage defines a message struct. It describes
|
||||
// the created time, where it from, status, ID of the
|
||||
// message. It's used for docker events.
|
||||
type Message struct {
|
||||
Stream string `json:"stream,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Progress *Progress `json:"progressDetail,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Error *Error `json:"errorDetail,omitempty"`
|
||||
Aux *json.RawMessage `json:"aux,omitempty"` // Aux contains out-of-band data, such as digests for push signing and image id after building.
|
||||
}
|
||||
@@ -14,25 +14,6 @@ import (
|
||||
"github.com/moby/moby/client/pkg/progress"
|
||||
)
|
||||
|
||||
// jsonMessage defines a message struct. It describes
|
||||
// the created time, where it from, status, ID of the
|
||||
// message. It's used for docker events.
|
||||
//
|
||||
// It is a reduced set of [jsonmessage.JSONMessage].
|
||||
type jsonMessage struct {
|
||||
Stream string `json:"stream,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Progress *jsonstream.Progress `json:"progressDetail,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Error *jsonstream.Error `json:"errorDetail,omitempty"`
|
||||
Aux *json.RawMessage `json:"aux,omitempty"` // Aux contains out-of-band data, such as digests for push signing and image id after building.
|
||||
|
||||
// ErrorMessage contains errors encountered during the operation.
|
||||
//
|
||||
// Deprecated: this field is deprecated since docker v0.6.0 / API v1.4. Use [Error.Message] instead. This field will be omitted in a future release.
|
||||
ErrorMessage string `json:"error,omitempty"` // deprecated
|
||||
}
|
||||
|
||||
const streamNewline = "\r\n"
|
||||
|
||||
type jsonProgressFormatter struct{}
|
||||
@@ -44,7 +25,7 @@ func appendNewline(source []byte) []byte {
|
||||
// FormatStatus formats the specified objects according to the specified format (and id).
|
||||
func FormatStatus(id, format string, a ...any) []byte {
|
||||
str := fmt.Sprintf(format, a...)
|
||||
b, err := json.Marshal(&jsonMessage{ID: id, Status: str})
|
||||
b, err := json.Marshal(&jsonstream.Message{ID: id, Status: str})
|
||||
if err != nil {
|
||||
return FormatError(err)
|
||||
}
|
||||
@@ -57,7 +38,7 @@ func FormatError(err error) []byte {
|
||||
if !ok {
|
||||
jsonError = &jsonstream.Error{Message: err.Error()}
|
||||
}
|
||||
if b, err := json.Marshal(&jsonMessage{Error: jsonError, ErrorMessage: err.Error()}); err == nil {
|
||||
if b, err := json.Marshal(&jsonstream.Message{Error: jsonError}); err == nil {
|
||||
return appendNewline(b)
|
||||
}
|
||||
return []byte(`{"error":"format error"}` + streamNewline)
|
||||
@@ -81,7 +62,7 @@ func (sf *jsonProgressFormatter) formatProgress(id, action string, progress *jso
|
||||
auxJSON = new(json.RawMessage)
|
||||
*auxJSON = auxJSONBytes
|
||||
}
|
||||
b, err := json.Marshal(&jsonMessage{
|
||||
b, err := json.Marshal(&jsonstream.Message{
|
||||
Status: action,
|
||||
Progress: progress,
|
||||
ID: id,
|
||||
@@ -234,7 +215,7 @@ func (sf *AuxFormatter) Emit(id string, aux any) error {
|
||||
}
|
||||
auxJSON := new(json.RawMessage)
|
||||
*auxJSON = auxJSONBytes
|
||||
msgJSON, err := json.Marshal(&jsonMessage{ID: id, Aux: auxJSON})
|
||||
msgJSON, err := json.Marshal(&jsonstream.Message{ID: id, Aux: auxJSON})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -41,14 +41,14 @@ func TestFormatStatus(t *testing.T) {
|
||||
|
||||
func TestFormatError(t *testing.T) {
|
||||
res := FormatError(errors.New("Error for formatter"))
|
||||
expected := `{"errorDetail":{"message":"Error for formatter"},"error":"Error for formatter"}` + "\r\n"
|
||||
expected := `{"errorDetail":{"message":"Error for formatter"}}` + "\r\n"
|
||||
assert.Check(t, is.Equal(expected, string(res)))
|
||||
}
|
||||
|
||||
func TestFormatJSONError(t *testing.T) {
|
||||
err := &jsonstream.Error{Code: 50, Message: "Json error"}
|
||||
res := FormatError(err)
|
||||
expected := `{"errorDetail":{"code":50,"message":"Json error"},"error":"Json error"}` + streamNewline
|
||||
expected := `{"errorDetail":{"code":50,"message":"Json error"}}` + streamNewline
|
||||
assert.Check(t, is.Equal(expected, string(res)))
|
||||
}
|
||||
|
||||
@@ -61,12 +61,12 @@ func TestJsonProgressFormatterFormatProgress(t *testing.T) {
|
||||
}
|
||||
aux := "aux message"
|
||||
res := sf.formatProgress("id", "action", jsonProgress, aux)
|
||||
msg := &jsonMessage{}
|
||||
msg := &jsonstream.Message{}
|
||||
|
||||
assert.NilError(t, json.Unmarshal(res, msg))
|
||||
|
||||
rawAux := json.RawMessage(`"` + aux + `"`)
|
||||
expected := &jsonMessage{
|
||||
expected := &jsonstream.Message{
|
||||
ID: "id",
|
||||
Status: "action",
|
||||
Aux: &rawAux,
|
||||
|
||||
@@ -3,6 +3,8 @@ package streamformatter
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"github.com/moby/moby/api/types/jsonstream"
|
||||
)
|
||||
|
||||
type streamWriter struct {
|
||||
@@ -20,7 +22,7 @@ func (sw *streamWriter) Write(buf []byte) (int, error) {
|
||||
}
|
||||
|
||||
func (sw *streamWriter) format(buf []byte) []byte {
|
||||
msg := &jsonMessage{Stream: sw.lineFormat(buf)}
|
||||
msg := &jsonstream.Message{Stream: sw.lineFormat(buf)}
|
||||
b, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
return FormatError(err)
|
||||
|
||||
@@ -8,28 +8,10 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/moby/moby/api/types/jsonstream"
|
||||
"github.com/moby/moby/v2/daemon/internal/compat"
|
||||
"github.com/moby/moby/v2/daemon/internal/progress"
|
||||
)
|
||||
|
||||
// jsonMessage defines a message struct. It describes
|
||||
// the created time, where it from, status, ID of the
|
||||
// message. It's used for docker events.
|
||||
//
|
||||
// It is a reduced set of [jsonmessage.JSONMessage].
|
||||
type jsonMessage struct {
|
||||
Stream string `json:"stream,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Progress *jsonstream.Progress `json:"progressDetail,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Error *jsonstream.Error `json:"errorDetail,omitempty"`
|
||||
Aux *json.RawMessage `json:"aux,omitempty"` // Aux contains out-of-band data, such as digests for push signing and image id after building.
|
||||
|
||||
// ErrorMessage contains errors encountered during the operation.
|
||||
//
|
||||
// Deprecated: this field is deprecated since docker v0.6.0 / API v1.4. Use [Error.Message] instead. This field will be omitted in a future release.
|
||||
ErrorMessage string `json:"error,omitempty"` // deprecated
|
||||
}
|
||||
|
||||
const streamNewline = "\r\n"
|
||||
|
||||
type jsonProgressFormatter struct{}
|
||||
@@ -41,7 +23,7 @@ func appendNewline(source []byte) []byte {
|
||||
// FormatStatus formats the specified objects according to the specified format (and id).
|
||||
func FormatStatus(id, format string, a ...any) []byte {
|
||||
str := fmt.Sprintf(format, a...)
|
||||
b, err := json.Marshal(&jsonMessage{ID: id, Status: str})
|
||||
b, err := json.Marshal(&jsonstream.Message{ID: id, Status: str})
|
||||
if err != nil {
|
||||
return FormatError(err)
|
||||
}
|
||||
@@ -54,7 +36,7 @@ func FormatError(err error) []byte {
|
||||
if !ok {
|
||||
jsonError = &jsonstream.Error{Message: err.Error()}
|
||||
}
|
||||
if b, err := json.Marshal(&jsonMessage{Error: jsonError, ErrorMessage: err.Error()}); err == nil {
|
||||
if b, err := json.Marshal(compat.Wrap(&jsonstream.Message{Error: jsonError}, compat.WithExtraFields(map[string]any{"error": jsonError.Error()}))); err == nil {
|
||||
return appendNewline(b)
|
||||
}
|
||||
return []byte(`{"error":"format error"}` + streamNewline)
|
||||
@@ -78,7 +60,7 @@ func (sf *jsonProgressFormatter) formatProgress(id, action string, progress *jso
|
||||
auxJSON = new(json.RawMessage)
|
||||
*auxJSON = auxJSONBytes
|
||||
}
|
||||
b, err := json.Marshal(&jsonMessage{
|
||||
b, err := json.Marshal(&jsonstream.Message{
|
||||
Status: action,
|
||||
Progress: progress,
|
||||
ID: id,
|
||||
@@ -151,7 +133,7 @@ func (sf *AuxFormatter) Emit(id string, aux any) error {
|
||||
}
|
||||
auxJSON := new(json.RawMessage)
|
||||
*auxJSON = auxJSONBytes
|
||||
msgJSON, err := json.Marshal(&jsonMessage{ID: id, Aux: auxJSON})
|
||||
msgJSON, err := json.Marshal(&jsonstream.Message{ID: id, Aux: auxJSON})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -20,14 +20,14 @@ func TestFormatStatus(t *testing.T) {
|
||||
|
||||
func TestFormatError(t *testing.T) {
|
||||
res := FormatError(errors.New("Error for formatter"))
|
||||
expected := `{"errorDetail":{"message":"Error for formatter"},"error":"Error for formatter"}` + "\r\n"
|
||||
expected := `{"error":"Error for formatter","errorDetail":{"message":"Error for formatter"}}` + "\r\n"
|
||||
assert.Check(t, is.Equal(expected, string(res)))
|
||||
}
|
||||
|
||||
func TestFormatJSONError(t *testing.T) {
|
||||
err := &jsonstream.Error{Code: 50, Message: "Json error"}
|
||||
res := FormatError(err)
|
||||
expected := `{"errorDetail":{"code":50,"message":"Json error"},"error":"Json error"}` + streamNewline
|
||||
expected := `{"error":"Json error","errorDetail":{"code":50,"message":"Json error"}}` + streamNewline
|
||||
assert.Check(t, is.Equal(expected, string(res)))
|
||||
}
|
||||
|
||||
@@ -40,12 +40,12 @@ func TestJsonProgressFormatterFormatProgress(t *testing.T) {
|
||||
}
|
||||
aux := "aux message"
|
||||
res := sf.formatProgress("id", "action", jsonProgress, aux)
|
||||
msg := &jsonMessage{}
|
||||
msg := &jsonstream.Message{}
|
||||
|
||||
assert.NilError(t, json.Unmarshal(res, msg))
|
||||
|
||||
rawAux := json.RawMessage(`"` + aux + `"`)
|
||||
expected := &jsonMessage{
|
||||
expected := &jsonstream.Message{
|
||||
ID: "id",
|
||||
Status: "action",
|
||||
Aux: &rawAux,
|
||||
|
||||
@@ -3,6 +3,8 @@ package streamformatter
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"github.com/moby/moby/api/types/jsonstream"
|
||||
)
|
||||
|
||||
type streamWriter struct {
|
||||
@@ -20,7 +22,7 @@ func (sw *streamWriter) Write(buf []byte) (int, error) {
|
||||
}
|
||||
|
||||
func (sw *streamWriter) format(buf []byte) []byte {
|
||||
msg := &jsonMessage{Stream: sw.lineFormat(buf)}
|
||||
msg := &jsonstream.Message{Stream: sw.lineFormat(buf)}
|
||||
b, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
return FormatError(err)
|
||||
|
||||
15
vendor/github.com/moby/moby/api/types/jsonstream/message.go
generated
vendored
Normal file
15
vendor/github.com/moby/moby/api/types/jsonstream/message.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
package jsonstream
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// JSONMessage defines a message struct. It describes
|
||||
// the created time, where it from, status, ID of the
|
||||
// message. It's used for docker events.
|
||||
type Message struct {
|
||||
Stream string `json:"stream,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Progress *Progress `json:"progressDetail,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Error *Error `json:"errorDetail,omitempty"`
|
||||
Aux *json.RawMessage `json:"aux,omitempty"` // Aux contains out-of-band data, such as digests for push signing and image id after building.
|
||||
}
|
||||
Reference in New Issue
Block a user