88 "time"
99
1010 "github.com/opencontainers/runtime-spec/specs-go"
11-
11+ "github.com/pkg/errors"
1212 "github.com/sirupsen/logrus"
1313)
1414
@@ -176,7 +176,7 @@ type Config struct {
176176
177177 // Hooks are a collection of actions to perform at various container lifecycle events.
178178 // CommandHooks are serialized to JSON, but other hooks are not.
179- Hooks * Hooks
179+ Hooks Hooks
180180
181181 // Version is the version of opencontainer specification that is supported.
182182 Version string `json:"version"`
@@ -203,17 +203,54 @@ type Config struct {
203203 RootlessCgroups bool `json:"rootless_cgroups,omitempty"`
204204}
205205
206- type Hooks struct {
206+ type HookName string
207+ type HookList []Hook
208+ type Hooks map [HookName ]HookList
209+
210+ const (
207211 // Prestart commands are executed after the container namespaces are created,
208212 // but before the user supplied command is executed from init.
209- Prestart []Hook
213+ // Note: This hook is now deprecated
214+ // Prestart commands are called in the Runtime namespace.
215+ Prestart HookName = "prestart"
216+
217+ // CreateRuntime commands MUST be called as part of the create operation after
218+ // the runtime environment has been created but before the pivot_root has been executed.
219+ // CreateRuntime is called immediately after the deprecated Prestart hook.
220+ // CreateRuntime commands are called in the Runtime Namespace.
221+ CreateRuntime = "createRuntime"
222+
223+ // CreateContainer commands MUST be called as part of the create operation after
224+ // the runtime environment has been created but before the pivot_root has been executed.
225+ // CreateContainer commands are called in the Container namespace.
226+ CreateContainer = "createContainer"
227+
228+ // StartContainer commands MUST be called as part of the start operation and before
229+ // the container process is started.
230+ // StartContainer commands are called in the Container namespace.
231+ StartContainer = "startContainer"
210232
211233 // Poststart commands are executed after the container init process starts.
212- Poststart []Hook
234+ // Poststart commands are called in the Runtime Namespace.
235+ Poststart = "poststart"
213236
214237 // Poststop commands are executed after the container init process exits.
215- Poststop []Hook
216- }
238+ // Poststop commands are called in the Runtime Namespace.
239+ Poststop = "poststop"
240+ )
241+
242+ var (
243+ HookNameList = []HookName {Prestart , CreateRuntime , CreateContainer , StartContainer , Poststart , Poststop }
244+ )
245+
246+ // TODO move this to runtime-spec
247+ // See: https://github.com/opencontainers/runtime-spec/pull/1046
248+ const (
249+ Creating = "creating"
250+ Created = "created"
251+ Running = "running"
252+ Stopped = "stopped"
253+ )
217254
218255type Capabilities struct {
219256 // Bounding is the set of capabilities checked by the kernel.
@@ -228,32 +265,39 @@ type Capabilities struct {
228265 Ambient []string
229266}
230267
231- func (hooks * Hooks ) UnmarshalJSON ( b [] byte ) error {
232- var state struct {
233- Prestart [] CommandHook
234- Poststart [] CommandHook
235- Poststop [] CommandHook
268+ func (hooks HookList ) RunHooks ( state * specs. State ) error {
269+ for i , h := range hooks {
270+ if err := h . Run ( state ); err != nil {
271+ return errors . Wrapf ( err , "Running hook #%d:" , i )
272+ }
236273 }
237274
275+ return nil
276+ }
277+
278+ func (hooks * Hooks ) UnmarshalJSON (b []byte ) error {
279+ var state map [HookName ][]CommandHook
280+
238281 if err := json .Unmarshal (b , & state ); err != nil {
239282 return err
240283 }
241284
242- deserialize := func (shooks []CommandHook ) (hooks []Hook ) {
243- for _ , shook := range shooks {
244- hooks = append (hooks , shook )
285+ * hooks = Hooks {}
286+ for n , commandHooks := range state {
287+ if len (commandHooks ) == 0 {
288+ continue
245289 }
246290
247- return hooks
291+ (* hooks )[n ] = HookList {}
292+ for _ , h := range commandHooks {
293+ (* hooks )[n ] = append ((* hooks )[n ], h )
294+ }
248295 }
249296
250- hooks .Prestart = deserialize (state .Prestart )
251- hooks .Poststart = deserialize (state .Poststart )
252- hooks .Poststop = deserialize (state .Poststop )
253297 return nil
254298}
255299
256- func (hooks Hooks ) MarshalJSON () ([]byte , error ) {
300+ func (hooks * Hooks ) MarshalJSON () ([]byte , error ) {
257301 serialize := func (hooks []Hook ) (serializableHooks []CommandHook ) {
258302 for _ , hook := range hooks {
259303 switch chook := hook .(type ) {
@@ -268,9 +312,12 @@ func (hooks Hooks) MarshalJSON() ([]byte, error) {
268312 }
269313
270314 return json .Marshal (map [string ]interface {}{
271- "prestart" : serialize (hooks .Prestart ),
272- "poststart" : serialize (hooks .Poststart ),
273- "poststop" : serialize (hooks .Poststop ),
315+ "prestart" : serialize ((* hooks )[Prestart ]),
316+ "createRuntime" : serialize ((* hooks )[CreateRuntime ]),
317+ "createContainer" : serialize ((* hooks )[CreateContainer ]),
318+ "startContainer" : serialize ((* hooks )[StartContainer ]),
319+ "poststart" : serialize ((* hooks )[Poststart ]),
320+ "poststop" : serialize ((* hooks )[Poststop ]),
274321 })
275322}
276323
0 commit comments