Swap from FFJSON to easyjson

FFJSON has serialization differences versus stock Go - namely, it
does not respect the MarshalText() and UnmarshalText() methods,
particularly on []byte, which causes incompatability with
pre-FFJSON containers which contained DNS servers.

EasyJSON does not have these issues, and might even be slightly
faster.

Signed-off-by: Matthew Heon <matthew.heon@gmail.com>

Closes: #1322
Approved by: mheon
This commit is contained in:
Matthew Heon
2018-08-22 09:12:40 -04:00
committed by Atomic Bot
parent bd080b4530
commit 714dbbda9e
10 changed files with 8198 additions and 8155 deletions

View File

@ -104,11 +104,11 @@ RUN set -x \
&& export GOPATH=/go \
&& go get github.com/onsi/gomega/...
# Install ffjson
# Install easyjson
RUN set -x \
&& export GOPATH=/go \
&& go get github.com/pquerna/ffjson \
&& install -D -m 755 "$GOPATH"/bin/ffjson /usr/bin/
&& go get -u github.com/mailru/easyjson/... \
&& install -D -m 755 "$GOPATH"/bin/easyjson /usr/bin/
# Install cni config
#RUN make install.cni

View File

@ -61,11 +61,11 @@ RUN set -x \
&& export GOPATH=/go \
&& go get github.com/onsi/gomega/...
# Install ffjson
# Install easyjson
RUN set -x \
&& export GOPATH=/go \
&& go get github.com/pquerna/ffjson \
&& install -D -m 755 "$GOPATH"/bin/ffjson /usr/bin/
&& go get -u github.com/mailru/easyjson/... \
&& install -D -m 755 "$GOPATH"/bin/easyjson /usr/bin/
# Install conmon
ENV CRIO_COMMIT 662dbb31b5d4f5ed54511a47cde7190c61c28677

View File

@ -63,11 +63,11 @@ RUN set -x \
&& export GOPATH=/go \
&& go get github.com/onsi/gomega/...
# Install ffjson
# Install easyjson
RUN set -x \
&& export GOPATH=/go \
&& go get github.com/pquerna/ffjson \
&& install -D -m 755 "$GOPATH"/bin/ffjson /usr/bin/
&& go get -u github.com/mailru/easyjson/... \
&& install -D -m 755 "$GOPATH"/bin/easyjson /usr/bin/
# Install conmon
ENV CRIO_COMMIT 662dbb31b5d4f5ed54511a47cde7190c61c28677

View File

@ -135,6 +135,8 @@ clean:
cmd/podman/varlink/iopodman.go \
libpod/container_ffjson.go \
libpod/pod_ffjson.go \
libpod/container_easyjson.go \
libpod/pod_easyjson.go \
$(MANPAGES) ||:
ifdef HAS_PYTHON3
$(MAKE) -C contrib/python/podman clean
@ -183,7 +185,7 @@ clientintegration:
vagrant-check:
BOX=$(BOX) sh ./vagrant.sh
binaries: varlink_generate ffjson_generate podman python
binaries: varlink_generate easyjson_generate podman python
test-binaries: test/bin2img/bin2img test/copyimg/copyimg test/checkseccomp/checkseccomp
@ -262,7 +264,7 @@ uninstall:
.PHONY: install.tools
install.tools: .install.gitvalidation .install.gometalinter .install.md2man .install.ffjson
install.tools: .install.gitvalidation .install.gometalinter .install.md2man .install.easyjson
.install.gitvalidation: .gopathok
if [ ! -x "$(GOBIN)/git-validation" ]; then \
@ -283,9 +285,9 @@ install.tools: .install.gitvalidation .install.gometalinter .install.md2man .ins
$(GO) get -u github.com/cpuguy83/go-md2man; \
fi
.install.ffjson: .gopathok
.install.easyjson: .gopathok
if [ ! -x "$(GOBIN)/ffjson" ]; then\
$(GO) get -u github.com/pquerna/ffjson; \
$(GO) get -u github.com/mailru/easyjson/...; \
fi
.install.ostree: .gopathok
@ -299,15 +301,15 @@ install.tools: .install.gitvalidation .install.gometalinter .install.md2man .ins
varlink_generate: .gopathok cmd/podman/varlink/iopodman.go
varlink_api_generate: .gopathok API.md
ffjson_generate: .gopathok libpod/container_ffjson.go libpod/pod_ffjson.go
easyjson_generate: .gopathok libpod/container_easyjson.go libpod/pod_easyjson.go
libpod/container_ffjson.go: libpod/container.go
rm -f libpod/container_ffjson.go
ffjson $(GOPKGDIR)/libpod/container.go
libpod/container_easyjson.go: libpod/container.go
rm -f libpod/container_easyjson.go
cd "$(GOPKGDIR)" && easyjson ./libpod/container.go
libpod/pod_ffjson.go: libpod/pod.go
rm -f libpod/pod_ffjson.go
ffjson $(GOPKGDIR)/libpod/pod.go
libpod/pod_easyjson.go: libpod/pod.go
rm -f libpod/pod_easyjson.go
cd "$(GOPKGDIR)" && easyjson ./libpod/pod.go
.PHONY: install.libseccomp.sudo
install.libseccomp.sudo:

View File

@ -123,6 +123,7 @@ type Container struct {
// containerState contains the current state of the container
// It is stored on disk in a tmpfs and recreated on reboot
// easyjson:json
type containerState struct {
// The current state of the running container
State ContainerStatus `json:"state"`
@ -183,6 +184,7 @@ type containerState struct {
}
// ExecSession contains information on an active exec session
// easyjson:json
type ExecSession struct {
ID string `json:"id"`
Command []string `json:"command"`
@ -192,6 +194,7 @@ type ExecSession struct {
// ContainerConfig contains all information that was used to create the
// container. It may not be changed once created.
// It is stored, read-only, on disk
// easyjson:json
type ContainerConfig struct {
Spec *spec.Spec `json:"spec"`
ID string `json:"id"`

7594
libpod/container_easyjson.go Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@ type Pod struct {
}
// PodConfig represents a pod's static configuration
// easyjson:json
type PodConfig struct {
ID string `json:"id"`
Name string `json:"name"`
@ -61,6 +62,7 @@ type PodConfig struct {
}
// podState represents a pod's state
// easyjson:json
type podState struct {
// CgroupPath is the path to the pod's CGroup
CgroupPath string `json:"cgroupPath"`
@ -71,6 +73,7 @@ type podState struct {
// PodInspect represents the data we want to display for
// podman pod inspect
// easyjson:json
type PodInspect struct {
Config *PodConfig
State *PodInspectState
@ -78,12 +81,14 @@ type PodInspect struct {
}
// PodInspectState contains inspect data on the pod's state
// easyjson:json
type PodInspectState struct {
CgroupPath string `json:"cgroupPath"`
InfraContainerID string `json:"infraContainerID"`
}
// PodContainerInfo keeps information on a container in a pod
// easyjson:json
type PodContainerInfo struct {
ID string `json:"id"`
State string `json:"state"`

574
libpod/pod_easyjson.go Normal file
View File

@ -0,0 +1,574 @@
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
package libpod
import (
json "encoding/json"
easyjson "github.com/mailru/easyjson"
jlexer "github.com/mailru/easyjson/jlexer"
jwriter "github.com/mailru/easyjson/jwriter"
)
// suppress unused package warning
var (
_ *json.RawMessage
_ *jlexer.Lexer
_ *jwriter.Writer
_ easyjson.Marshaler
)
func easyjsonBe091417DecodeGithubComContainersLibpodLibpod(in *jlexer.Lexer, out *podState) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeString()
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "cgroupPath":
out.CgroupPath = string(in.String())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonBe091417EncodeGithubComContainersLibpodLibpod(out *jwriter.Writer, in podState) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"cgroupPath\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
out.String(string(in.CgroupPath))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v podState) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonBe091417EncodeGithubComContainersLibpodLibpod(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v podState) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonBe091417EncodeGithubComContainersLibpodLibpod(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *podState) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonBe091417DecodeGithubComContainersLibpodLibpod(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *podState) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonBe091417DecodeGithubComContainersLibpodLibpod(l, v)
}
func easyjsonBe091417DecodeGithubComContainersLibpodLibpod1(in *jlexer.Lexer, out *PodInspectState) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeString()
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "cgroupPath":
out.CgroupPath = string(in.String())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonBe091417EncodeGithubComContainersLibpodLibpod1(out *jwriter.Writer, in PodInspectState) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"cgroupPath\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
out.String(string(in.CgroupPath))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v PodInspectState) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonBe091417EncodeGithubComContainersLibpodLibpod1(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v PodInspectState) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonBe091417EncodeGithubComContainersLibpodLibpod1(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *PodInspectState) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonBe091417DecodeGithubComContainersLibpodLibpod1(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *PodInspectState) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonBe091417DecodeGithubComContainersLibpodLibpod1(l, v)
}
func easyjsonBe091417DecodeGithubComContainersLibpodLibpod2(in *jlexer.Lexer, out *PodInspect) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeString()
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "Config":
if in.IsNull() {
in.Skip()
out.Config = nil
} else {
if out.Config == nil {
out.Config = new(PodConfig)
}
(*out.Config).UnmarshalEasyJSON(in)
}
case "State":
if in.IsNull() {
in.Skip()
out.State = nil
} else {
if out.State == nil {
out.State = new(PodInspectState)
}
(*out.State).UnmarshalEasyJSON(in)
}
case "Containers":
if in.IsNull() {
in.Skip()
out.Containers = nil
} else {
in.Delim('[')
if out.Containers == nil {
if !in.IsDelim(']') {
out.Containers = make([]PodContainerInfo, 0, 2)
} else {
out.Containers = []PodContainerInfo{}
}
} else {
out.Containers = (out.Containers)[:0]
}
for !in.IsDelim(']') {
var v1 PodContainerInfo
(v1).UnmarshalEasyJSON(in)
out.Containers = append(out.Containers, v1)
in.WantComma()
}
in.Delim(']')
}
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonBe091417EncodeGithubComContainersLibpodLibpod2(out *jwriter.Writer, in PodInspect) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"Config\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
if in.Config == nil {
out.RawString("null")
} else {
(*in.Config).MarshalEasyJSON(out)
}
}
{
const prefix string = ",\"State\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
if in.State == nil {
out.RawString("null")
} else {
(*in.State).MarshalEasyJSON(out)
}
}
{
const prefix string = ",\"Containers\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
if in.Containers == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
out.RawString("null")
} else {
out.RawByte('[')
for v2, v3 := range in.Containers {
if v2 > 0 {
out.RawByte(',')
}
(v3).MarshalEasyJSON(out)
}
out.RawByte(']')
}
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v PodInspect) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonBe091417EncodeGithubComContainersLibpodLibpod2(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v PodInspect) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonBe091417EncodeGithubComContainersLibpodLibpod2(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *PodInspect) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonBe091417DecodeGithubComContainersLibpodLibpod2(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *PodInspect) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonBe091417DecodeGithubComContainersLibpodLibpod2(l, v)
}
func easyjsonBe091417DecodeGithubComContainersLibpodLibpod3(in *jlexer.Lexer, out *PodContainerInfo) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeString()
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "id":
out.ID = string(in.String())
case "state":
out.State = string(in.String())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonBe091417EncodeGithubComContainersLibpodLibpod3(out *jwriter.Writer, in PodContainerInfo) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"id\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
out.String(string(in.ID))
}
{
const prefix string = ",\"state\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
out.String(string(in.State))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v PodContainerInfo) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonBe091417EncodeGithubComContainersLibpodLibpod3(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v PodContainerInfo) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonBe091417EncodeGithubComContainersLibpodLibpod3(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *PodContainerInfo) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonBe091417DecodeGithubComContainersLibpodLibpod3(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *PodContainerInfo) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonBe091417DecodeGithubComContainersLibpodLibpod3(l, v)
}
func easyjsonBe091417DecodeGithubComContainersLibpodLibpod4(in *jlexer.Lexer, out *PodConfig) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeString()
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "id":
out.ID = string(in.String())
case "name":
out.Name = string(in.String())
case "namespace":
out.Namespace = string(in.String())
case "labels":
if in.IsNull() {
in.Skip()
} else {
in.Delim('{')
if !in.IsDelim('}') {
out.Labels = make(map[string]string)
} else {
out.Labels = nil
}
for !in.IsDelim('}') {
key := string(in.String())
in.WantColon()
var v4 string
v4 = string(in.String())
(out.Labels)[key] = v4
in.WantComma()
}
in.Delim('}')
}
case "cgroupParent":
out.CgroupParent = string(in.String())
case "usePodCgroup":
out.UsePodCgroup = bool(in.Bool())
case "created":
if data := in.Raw(); in.Ok() {
in.AddError((out.CreatedTime).UnmarshalJSON(data))
}
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonBe091417EncodeGithubComContainersLibpodLibpod4(out *jwriter.Writer, in PodConfig) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"id\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
out.String(string(in.ID))
}
{
const prefix string = ",\"name\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
out.String(string(in.Name))
}
if in.Namespace != "" {
const prefix string = ",\"namespace\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
out.String(string(in.Namespace))
}
{
const prefix string = ",\"labels\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
if in.Labels == nil && (out.Flags&jwriter.NilMapAsEmpty) == 0 {
out.RawString(`null`)
} else {
out.RawByte('{')
v5First := true
for v5Name, v5Value := range in.Labels {
if v5First {
v5First = false
} else {
out.RawByte(',')
}
out.String(string(v5Name))
out.RawByte(':')
out.String(string(v5Value))
}
out.RawByte('}')
}
}
{
const prefix string = ",\"cgroupParent\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
out.String(string(in.CgroupParent))
}
{
const prefix string = ",\"usePodCgroup\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
out.Bool(bool(in.UsePodCgroup))
}
{
const prefix string = ",\"created\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
out.Raw((in.CreatedTime).MarshalJSON())
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v PodConfig) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonBe091417EncodeGithubComContainersLibpodLibpod4(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v PodConfig) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonBe091417EncodeGithubComContainersLibpodLibpod4(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *PodConfig) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonBe091417DecodeGithubComContainersLibpodLibpod4(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *PodConfig) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonBe091417DecodeGithubComContainersLibpodLibpod4(l, v)
}

File diff suppressed because it is too large Load Diff