From 3ef9279cec43ca7e24fb00eb838d85e30b7e37f7 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Sat, 11 Aug 2018 11:19:08 -0400 Subject: Ensure pod inspect is locked and validity-checked Also, don't return the internal podState struct - instead return a public inspect struct. Signed-off-by: Matthew Heon Closes: #1258 Approved by: rhatdan --- libpod/pod.go | 11 ++- libpod/pod_api.go | 14 +++- libpod/pod_ffjson.go | 226 +++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 229 insertions(+), 22 deletions(-) (limited to 'libpod') diff --git a/libpod/pod.go b/libpod/pod.go index 24469fea8..5d762190b 100644 --- a/libpod/pod.go +++ b/libpod/pod.go @@ -41,7 +41,7 @@ type PodConfig struct { // join containers to it. // If true, all containers joined to the pod will use the pod cgroup as // their cgroup parent, and cannot set a different cgroup parent - UsePodCgroup bool + UsePodCgroup bool `json:"usePodCgroup"` // Time pod was created CreatedTime time.Time `json:"created"` @@ -50,17 +50,22 @@ type PodConfig struct { // podState represents a pod's state type podState struct { // CgroupPath is the path to the pod's CGroup - CgroupPath string + CgroupPath string `json:"cgroupPath"` } // PodInspect represents the data we want to display for // podman pod inspect type PodInspect struct { Config *PodConfig - State *podState + State *PodInspectState Containers []PodContainerInfo } +// PodInspectState contains inspect data on the pod's state +type PodInspectState struct { + CgroupPath string `json:"cgroupPath"` +} + // PodContainerInfo keeps information on a container in a pod type PodContainerInfo struct { ID string `json:"id"` diff --git a/libpod/pod_api.go b/libpod/pod_api.go index 82c19e2b5..82cf7b727 100644 --- a/libpod/pod_api.go +++ b/libpod/pod_api.go @@ -398,7 +398,13 @@ func (p *Pod) Inspect() (*PodInspect, error) { podContainers []PodContainerInfo ) - containers, err := p.AllContainers() + p.lock.Lock() + defer p.lock.Unlock() + if err := p.updatePod(); err != nil { + return nil, err + } + + containers, err := p.runtime.state.PodContainers(p) if err != nil { return &PodInspect{}, err } @@ -420,8 +426,10 @@ func (p *Pod) Inspect() (*PodInspect, error) { config := new(PodConfig) deepcopier.Copy(p.config).To(config) inspectData := PodInspect{ - Config: config, - State: p.state, + Config: config, + State: &PodInspectState{ + CgroupPath: p.state.CgroupPath, + }, Containers: podContainers, } return &inspectData, nil diff --git a/libpod/pod_ffjson.go b/libpod/pod_ffjson.go index 3d7140b68..58b08d61b 100644 --- a/libpod/pod_ffjson.go +++ b/libpod/pod_ffjson.go @@ -60,9 +60,9 @@ func (j *PodConfig) MarshalJSONBuf(buf fflib.EncodingBuffer) error { buf.WriteString(`,"cgroupParent":`) fflib.WriteJsonString(buf, string(j.CgroupParent)) if j.UsePodCgroup { - buf.WriteString(`,"UsePodCgroup":true`) + buf.WriteString(`,"usePodCgroup":true`) } else { - buf.WriteString(`,"UsePodCgroup":false`) + buf.WriteString(`,"usePodCgroup":false`) } buf.WriteString(`,"created":`) @@ -108,7 +108,7 @@ var ffjKeyPodConfigLabels = []byte("labels") var ffjKeyPodConfigCgroupParent = []byte("cgroupParent") -var ffjKeyPodConfigUsePodCgroup = []byte("UsePodCgroup") +var ffjKeyPodConfigUsePodCgroup = []byte("usePodCgroup") var ffjKeyPodConfigCreatedTime = []byte("created") @@ -173,14 +173,6 @@ mainparse: } else { switch kn[0] { - case 'U': - - if bytes.Equal(ffjKeyPodConfigUsePodCgroup, kn) { - currentKey = ffjtPodConfigUsePodCgroup - state = fflib.FFParse_want_colon - goto mainparse - } - case 'c': if bytes.Equal(ffjKeyPodConfigCgroupParent, kn) { @@ -223,6 +215,14 @@ mainparse: goto mainparse } + case 'u': + + if bytes.Equal(ffjKeyPodConfigUsePodCgroup, kn) { + currentKey = ffjtPodConfigUsePodCgroup + state = fflib.FFParse_want_colon + goto mainparse + } + } if fflib.SimpleLetterEqualFold(ffjKeyPodConfigCreatedTime, kn) { @@ -1113,7 +1113,7 @@ handle_Config: handle_State: - /* handler: j.State type=libpod.podState kind=struct quoted=false*/ + /* handler: j.State type=libpod.PodInspectState kind=struct quoted=false*/ { if tok == fflib.FFTok_null { @@ -1123,7 +1123,7 @@ handle_State: } else { if j.State == nil { - j.State = new(podState) + j.State = new(PodInspectState) } err = j.State.UnmarshalJSONFFLexer(fs, fflib.FFParse_want_key) @@ -1223,6 +1223,200 @@ done: return nil } +// MarshalJSON marshal bytes to json - template +func (j *PodInspectState) MarshalJSON() ([]byte, error) { + var buf fflib.Buffer + if j == nil { + buf.WriteString("null") + return buf.Bytes(), nil + } + err := j.MarshalJSONBuf(&buf) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// MarshalJSONBuf marshal buff to json - template +func (j *PodInspectState) MarshalJSONBuf(buf fflib.EncodingBuffer) error { + if j == nil { + buf.WriteString("null") + return nil + } + var err error + var obj []byte + _ = obj + _ = err + buf.WriteString(`{"cgroupPath":`) + fflib.WriteJsonString(buf, string(j.CgroupPath)) + buf.WriteByte('}') + return nil +} + +const ( + ffjtPodInspectStatebase = iota + ffjtPodInspectStatenosuchkey + + ffjtPodInspectStateCgroupPath +) + +var ffjKeyPodInspectStateCgroupPath = []byte("cgroupPath") + +// UnmarshalJSON umarshall json - template of ffjson +func (j *PodInspectState) UnmarshalJSON(input []byte) error { + fs := fflib.NewFFLexer(input) + return j.UnmarshalJSONFFLexer(fs, fflib.FFParse_map_start) +} + +// UnmarshalJSONFFLexer fast json unmarshall - template ffjson +func (j *PodInspectState) UnmarshalJSONFFLexer(fs *fflib.FFLexer, state fflib.FFParseState) error { + var err error + currentKey := ffjtPodInspectStatebase + _ = currentKey + tok := fflib.FFTok_init + wantedTok := fflib.FFTok_init + +mainparse: + for { + tok = fs.Scan() + // println(fmt.Sprintf("debug: tok: %v state: %v", tok, state)) + if tok == fflib.FFTok_error { + goto tokerror + } + + switch state { + + case fflib.FFParse_map_start: + if tok != fflib.FFTok_left_bracket { + wantedTok = fflib.FFTok_left_bracket + goto wrongtokenerror + } + state = fflib.FFParse_want_key + continue + + case fflib.FFParse_after_value: + if tok == fflib.FFTok_comma { + state = fflib.FFParse_want_key + } else if tok == fflib.FFTok_right_bracket { + goto done + } else { + wantedTok = fflib.FFTok_comma + goto wrongtokenerror + } + + case fflib.FFParse_want_key: + // json {} ended. goto exit. woo. + if tok == fflib.FFTok_right_bracket { + goto done + } + if tok != fflib.FFTok_string { + wantedTok = fflib.FFTok_string + goto wrongtokenerror + } + + kn := fs.Output.Bytes() + if len(kn) <= 0 { + // "" case. hrm. + currentKey = ffjtPodInspectStatenosuchkey + state = fflib.FFParse_want_colon + goto mainparse + } else { + switch kn[0] { + + case 'c': + + if bytes.Equal(ffjKeyPodInspectStateCgroupPath, kn) { + currentKey = ffjtPodInspectStateCgroupPath + state = fflib.FFParse_want_colon + goto mainparse + } + + } + + if fflib.SimpleLetterEqualFold(ffjKeyPodInspectStateCgroupPath, kn) { + currentKey = ffjtPodInspectStateCgroupPath + state = fflib.FFParse_want_colon + goto mainparse + } + + currentKey = ffjtPodInspectStatenosuchkey + state = fflib.FFParse_want_colon + goto mainparse + } + + case fflib.FFParse_want_colon: + if tok != fflib.FFTok_colon { + wantedTok = fflib.FFTok_colon + goto wrongtokenerror + } + state = fflib.FFParse_want_value + continue + case fflib.FFParse_want_value: + + if tok == fflib.FFTok_left_brace || tok == fflib.FFTok_left_bracket || tok == fflib.FFTok_integer || tok == fflib.FFTok_double || tok == fflib.FFTok_string || tok == fflib.FFTok_bool || tok == fflib.FFTok_null { + switch currentKey { + + case ffjtPodInspectStateCgroupPath: + goto handle_CgroupPath + + case ffjtPodInspectStatenosuchkey: + err = fs.SkipField(tok) + if err != nil { + return fs.WrapErr(err) + } + state = fflib.FFParse_after_value + goto mainparse + } + } else { + goto wantedvalue + } + } + } + +handle_CgroupPath: + + /* handler: j.CgroupPath type=string kind=string quoted=false*/ + + { + + { + if tok != fflib.FFTok_string && tok != fflib.FFTok_null { + return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok)) + } + } + + if tok == fflib.FFTok_null { + + } else { + + outBuf := fs.Output.Bytes() + + j.CgroupPath = string(string(outBuf)) + + } + } + + state = fflib.FFParse_after_value + goto mainparse + +wantedvalue: + return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok)) +wrongtokenerror: + return fs.WrapErr(fmt.Errorf("ffjson: wanted token: %v, but got token: %v output=%s", wantedTok, tok, fs.Output.String())) +tokerror: + if fs.BigError != nil { + return fs.WrapErr(fs.BigError) + } + err = fs.Error.ToError() + if err != nil { + return fs.WrapErr(err) + } + panic("ffjson-generated: unreachable, please report bug.") +done: + + return nil +} + // MarshalJSON marshal bytes to json - template func (j *podState) MarshalJSON() ([]byte, error) { var buf fflib.Buffer @@ -1247,7 +1441,7 @@ func (j *podState) MarshalJSONBuf(buf fflib.EncodingBuffer) error { var obj []byte _ = obj _ = err - buf.WriteString(`{"CgroupPath":`) + buf.WriteString(`{"cgroupPath":`) fflib.WriteJsonString(buf, string(j.CgroupPath)) buf.WriteByte('}') return nil @@ -1260,7 +1454,7 @@ const ( ffjtpodStateCgroupPath ) -var ffjKeypodStateCgroupPath = []byte("CgroupPath") +var ffjKeypodStateCgroupPath = []byte("cgroupPath") // UnmarshalJSON umarshall json - template of ffjson func (j *podState) UnmarshalJSON(input []byte) error { @@ -1323,7 +1517,7 @@ mainparse: } else { switch kn[0] { - case 'C': + case 'c': if bytes.Equal(ffjKeypodStateCgroupPath, kn) { currentKey = ffjtpodStateCgroupPath -- cgit v1.2.3-54-g00ecf