diff --git a/examples/pod_runtime.json b/examples/pod_runtime.json index 65dc4197..5670052d 100644 --- a/examples/pod_runtime.json +++ b/examples/pod_runtime.json @@ -102,5 +102,6 @@ "name": "ip-address", "value": "10.1.2.3" } - ] + ], + "restartPolicy": "onFailure" } diff --git a/schema/pod.go b/schema/pod.go index 47e0340c..a9955f7a 100644 --- a/schema/pod.go +++ b/schema/pod.go @@ -25,13 +25,14 @@ import ( const PodManifestKind = types.ACKind("PodManifest") type PodManifest struct { - ACVersion types.SemVer `json:"acVersion"` - ACKind types.ACKind `json:"acKind"` - Apps AppList `json:"apps"` - Volumes []types.Volume `json:"volumes"` - Isolators []types.Isolator `json:"isolators"` - Annotations types.Annotations `json:"annotations"` - Ports []types.ExposedPort `json:"ports"` + ACVersion types.SemVer `json:"acVersion"` + ACKind types.ACKind `json:"acKind"` + Apps AppList `json:"apps"` + Volumes []types.Volume `json:"volumes"` + Isolators []types.Isolator `json:"isolators"` + Annotations types.Annotations `json:"annotations"` + Ports []types.ExposedPort `json:"ports"` + RestartPolicy types.RestartPolicy `json:"restartPolicy"` } // podManifest is a model to facilitate extra validation during the diff --git a/schema/types/restartpolicy.go b/schema/types/restartpolicy.go new file mode 100644 index 00000000..d87992c6 --- /dev/null +++ b/schema/types/restartpolicy.go @@ -0,0 +1,57 @@ +// Copyright 2015 The appc Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "encoding/json" + "fmt" +) + +type RestartPolicy string + +var validPolicies = map[RestartPolicy]struct{}{ + "always": struct{}{}, + "onFailure": struct{}{}, + "never": struct{}{}, +} + +type restartPolicy RestartPolicy + +func (r *RestartPolicy) UnmarshalJSON(data []byte) error { + var rp restartPolicy + if err := json.Unmarshal(data, &rp); err != nil { + return err + } + rr := RestartPolicy(rp) + if err := rr.assertValid(); err != nil { + return err + } + *r = rr + return nil +} + +func (r RestartPolicy) MarshalJSON() ([]byte, error) { + if err := r.assertValid(); err != nil { + return nil, err + } + return json.Marshal(restartPolicy(r)) +} + +func (r RestartPolicy) assertValid() error { + if _, ok := validPolicies[r]; !ok { + return fmt.Errorf("invalid restart policy %q", string(r)) + } + return nil +} diff --git a/schema/types/restartpolicy_test.go b/schema/types/restartpolicy_test.go new file mode 100644 index 00000000..3a72c38c --- /dev/null +++ b/schema/types/restartpolicy_test.go @@ -0,0 +1,34 @@ +// Copyright 2015 The appc Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "testing" +) + +func TestGoodRestartPolicy(t *testing.T) { + for e := range validPolicies { + if err := e.assertValid(); err != nil { + t.Errorf("good restart policy failed: %v", err) + } + } +} + +func TestBadRestartPolicy(t *testing.T) { + e := RestartPolicy("bad") + if err := e.assertValid(); err == nil { + t.Errorf("bad restart policy valid: %v", err) + } +} diff --git a/spec/pods.md b/spec/pods.md index 336dd26a..8a849625 100644 --- a/spec/pods.md +++ b/spec/pods.md @@ -150,7 +150,8 @@ JSON Schema for the Pod Manifest, conforming to [RFC4627](https://tools.ietf.org "name": "ftp", "hostPort": 2121 } - ] + ], + "restartPolicy": "onFailure" } ``` @@ -179,3 +180,7 @@ JSON Schema for the Pod Manifest, conforming to [RFC4627](https://tools.ietf.org * **ports** (list of objects, optional) list of ports that SHOULD be exposed on the host. * **name** (string, required, restricted to the [AC Name](#ac-name-type) formatting) name of the port to be exposed on the host. This field is a key referencing by name ports specified in the Image Manifest(s) of the app(s) within this Pod Manifest; consequently, port names MUST be unique among apps within a pod. * **hostPort** (integer, required) port number on the host that will be mapped to the application port. +* **restartPolicy** (string, optional) a string that specifies the restart policy that will be applied to all apps in the pod, if left empty, then the ACE can decide the default behavior. The ACE SHOULD also implement the exponential back-off delay when restarting the apps. Currently, the valid values for the restart policy include: + * **always** - the app will always restart when it exits, regardless of its exit status. + * **onFailure** - the app will only restart when it exits unsuccessfully, i.e., its exit status is non-zero. + * **never** - the app will never restart when it exits, regardless of its exit status.