diff --git a/go.mod b/go.mod index c57a66e..23b7682 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448 // indirect + github.com/creasty/defaults v1.3.0 // indirect github.com/docker/distribution v2.7.1+incompatible // indirect github.com/docker/docker v0.0.0-20180422163414-57142e89befe github.com/docker/go-connections v0.4.0 diff --git a/go.sum b/go.sum index 1ff9d63..8830a7d 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 h1:D21IyuvjDCshj1 github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448 h1:PUD50EuOMkXVcpBIA/R95d56duJR9VxhwncsFbNnxW4= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/creasty/defaults v1.3.0 h1:uG+RAxYbJgOPCOdKEcec9ZJXeva7Y6mj/8egdzwmLtw= +github.com/creasty/defaults v1.3.0/go.mod h1:CIEEvs7oIVZm30R8VxtFJs+4k201gReYyuYHJxZc68I= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v0.0.0-20180422163414-57142e89befe h1:VW8TnWi0CZgg7oCv0wH6evNwkzcJg/emnw4HrVIWws4= diff --git a/server/environment_docker.go b/server/environment_docker.go index 74fd2f9..5aee9d5 100644 --- a/server/environment_docker.go +++ b/server/environment_docker.go @@ -696,22 +696,15 @@ func (d *DockerEnvironment) exposedPorts() nat.PortSet { // Formats the resources available to a server instance in such as way that Docker will // generate a matching environment in the container. func (d *DockerEnvironment) getResourcesForServer() container.Resources { - b := true - oomDisabled := d.Server.Container.OomDisabled - - if oomDisabled == nil { - oomDisabled = &b - } - return container.Resources{ // @todo memory limit should be slightly higher than the reservation Memory: d.Server.Build.MemoryLimit * 1000000, MemoryReservation: d.Server.Build.MemoryLimit * 1000000, MemorySwap: d.Server.Build.ConvertedSwap(), - CPUQuota: d.Server.Build.ConvertedCpuLimit(), - CPUPeriod: 100000, - CPUShares: 1024, - BlkioWeight: d.Server.Build.IoWeight, - OomKillDisable: oomDisabled, + CPUQuota: d.Server.Build.ConvertedCpuLimit(), + CPUPeriod: 100000, + CPUShares: 1024, + BlkioWeight: d.Server.Build.IoWeight, + OomKillDisable: &d.Server.Container.OomDisabled, } } diff --git a/server/server.go b/server/server.go index c5f4872..ad93944 100644 --- a/server/server.go +++ b/server/server.go @@ -46,16 +46,16 @@ type Server struct { Image string `json:"image,omitempty"` // If set to true, OOM killer will be disabled on the server's Docker container. // If not present (nil) we will default to disabling it. - OomDisabled *bool `json:"oom_disabled,omitempty"` + OomDisabled bool `default:"false" json:"oom_disabled" yaml:"oom_disabled"` // Defines if the container needs to be rebuilt on the next boot. - RebuildRequired bool `json:"rebuild_required,omitempty"` + RebuildRequired bool `default:"false" json:"rebuild_required,omitempty" yaml:"rebuild_required"` } `json:"container,omitempty"` Environment Environment `json:"-" yaml:"-"` Filesystem *Filesystem `json:"-" yaml:"-"` - Resources *ResourceUsage `json:"resources"` + Resources *ResourceUsage `json:"resources" yaml:"-"` // Server cache used to store frequently requested information in memory and make // certain long operations return faster. For example, FS disk space usage. diff --git a/server/update.go b/server/update.go index 626f25f..7345965 100644 --- a/server/update.go +++ b/server/update.go @@ -2,6 +2,7 @@ package server import ( "encoding/json" + "github.com/buger/jsonparser" "github.com/imdario/mergo" "github.com/pkg/errors" ) @@ -19,12 +20,30 @@ func (s *Server) UpdateDataStructure(data []byte) error { return errors.WithStack(err) } + // Don't allow obviously corrupted data to pass through into this function. If the UUID + // doesn't match something has gone wrong and the API is attempting to meld this server + // instance into a totally different one, which would be bad. + if src.Uuid != s.Uuid { + return errors.New("attempting to merge a data stack with an invalid UUID") + } + // Merge the new data object that we have received with the existing server data object // and then save it to the disk so it is persistent. - if err := mergo.Merge(&s, src); err != nil { + if err := mergo.Merge(s, src, mergo.WithOverride); err != nil { return errors.WithStack(err) } + // Mergo can't quite handle this boolean value correctly, so for now we'll just + // handle this edge case manually since none of the other data passed through in this + // request is going to be boolean. Allegedly. + if v, err := jsonparser.GetBoolean(data, "container", "oom_disabled"); err != nil { + if err != jsonparser.KeyPathNotFoundError { + return errors.WithStack(err) + } + } else { + s.Container.OomDisabled = v + } + s.Container.RebuildRequired = true if _, err := s.WriteConfigurationToDisk(); err != nil { return errors.WithStack(err)