Merge pull request #24567 from yifan-gu/post_start_hook

Automatic merge from submit-queue

rkt: Add post-start hook support.

This adds a poll-and-timeout procedure after the pod is
started, to make sure the post-start hooks execute when the
container is actually running.

This is a temporal workaround for implementing post-hooks,
a long term solution is to use lifecycle event to trigger
those hooks, see https://github.com/kubernetes/kubernetes/issues/23084.

Also this fixes a bug of getting container ID for a non-running
container when running pre-stop hook.


cc @sjpotter @euank @kubernetes/sig-node
This commit is contained in:
k8s-merge-robot
2016-04-27 11:14:35 -07:00
4 changed files with 166 additions and 34 deletions

View File

@@ -1204,7 +1204,7 @@ func TestGenerateRunCommand(t *testing.T) {
}
}
func TestPreStopHooks(t *testing.T) {
func TestLifeCycleHooks(t *testing.T) {
runner := lifecycle.NewFakeHandlerRunner()
fr := newFakeRktInterface()
fs := newFakeSystemd()
@@ -1217,10 +1217,11 @@ func TestPreStopHooks(t *testing.T) {
}
tests := []struct {
pod *api.Pod
runtimePod *kubecontainer.Pod
preStopRuns []string
err error
pod *api.Pod
runtimePod *kubecontainer.Pod
postStartRuns []string
preStopRuns []string
err error
}{
{
// Case 0, container without any hooks.
@@ -1242,10 +1243,11 @@ func TestPreStopHooks(t *testing.T) {
},
},
[]string{},
[]string{},
nil,
},
{
// Case 1, containers with pre-stop hook.
// Case 1, containers with post-start and pre-stop hooks.
&api.Pod{
ObjectMeta: api.ObjectMeta{
Name: "pod-1",
@@ -1257,13 +1259,29 @@ func TestPreStopHooks(t *testing.T) {
{
Name: "container-name-1",
Lifecycle: &api.Lifecycle{
PreStop: &api.Handler{
PostStart: &api.Handler{
Exec: &api.ExecAction{},
},
},
},
{
Name: "container-name-2",
Lifecycle: &api.Lifecycle{
PostStart: &api.Handler{
HTTPGet: &api.HTTPGetAction{},
},
},
},
{
Name: "container-name-3",
Lifecycle: &api.Lifecycle{
PreStop: &api.Handler{
Exec: &api.ExecAction{},
},
},
},
{
Name: "container-name-4",
Lifecycle: &api.Lifecycle{
PreStop: &api.Handler{
HTTPGet: &api.HTTPGetAction{},
@@ -1275,13 +1293,31 @@ func TestPreStopHooks(t *testing.T) {
},
&kubecontainer.Pod{
Containers: []*kubecontainer.Container{
{ID: kubecontainer.BuildContainerID("rkt", "id-1")},
{ID: kubecontainer.BuildContainerID("rkt", "id-2")},
{
ID: kubecontainer.ParseContainerID("rkt://uuid:container-name-4"),
Name: "container-name-4",
},
{
ID: kubecontainer.ParseContainerID("rkt://uuid:container-name-3"),
Name: "container-name-3",
},
{
ID: kubecontainer.ParseContainerID("rkt://uuid:container-name-2"),
Name: "container-name-2",
},
{
ID: kubecontainer.ParseContainerID("rkt://uuid:container-name-1"),
Name: "container-name-1",
},
},
},
[]string{
"exec on pod: pod-1_ns-1(uid-1), container: container-name-1: rkt://id-1",
"http-get on pod: pod-1_ns-1(uid-1), container: container-name-2: rkt://id-2",
"exec on pod: pod-1_ns-1(uid-1), container: container-name-1: rkt://uuid:container-name-1",
"http-get on pod: pod-1_ns-1(uid-1), container: container-name-2: rkt://uuid:container-name-2",
},
[]string{
"exec on pod: pod-1_ns-1(uid-1), container: container-name-3: rkt://uuid:container-name-3",
"http-get on pod: pod-1_ns-1(uid-1), container: container-name-4: rkt://uuid:container-name-4",
},
nil,
},
@@ -1298,7 +1334,8 @@ func TestPreStopHooks(t *testing.T) {
{
Name: "container-name-1",
Lifecycle: &api.Lifecycle{
PreStop: &api.Handler{},
PostStart: &api.Handler{},
PreStop: &api.Handler{},
},
},
},
@@ -1306,10 +1343,14 @@ func TestPreStopHooks(t *testing.T) {
},
&kubecontainer.Pod{
Containers: []*kubecontainer.Container{
{ID: kubecontainer.BuildContainerID("rkt", "id-1")},
{
ID: kubecontainer.ParseContainerID("rkt://uuid:container-name-1"),
Name: "container-name-1",
},
},
},
[]string{},
[]string{},
errors.NewAggregate([]error{fmt.Errorf("Invalid handler: %v", &api.Handler{})}),
},
}
@@ -1317,8 +1358,28 @@ func TestPreStopHooks(t *testing.T) {
for i, tt := range tests {
testCaseHint := fmt.Sprintf("test case #%d", i)
pod := &rktapi.Pod{Id: "uuid"}
for _, c := range tt.runtimePod.Containers {
pod.Apps = append(pod.Apps, &rktapi.App{
Name: c.Name,
State: rktapi.AppState_APP_STATE_RUNNING,
})
}
fr.pods = []*rktapi.Pod{pod}
// Run post-start hooks
err := rkt.runLifecycleHooks(tt.pod, tt.runtimePod, lifecyclePostStartHook)
assert.Equal(t, tt.err, err, testCaseHint)
sort.Sort(sortedStringList(tt.postStartRuns))
sort.Sort(sortedStringList(runner.HandlerRuns))
assert.Equal(t, tt.postStartRuns, runner.HandlerRuns, testCaseHint)
runner.Reset()
// Run pre-stop hooks.
err := rkt.runPreStopHook(tt.pod, tt.runtimePod)
err = rkt.runLifecycleHooks(tt.pod, tt.runtimePod, lifecyclePreStopHook)
assert.Equal(t, tt.err, err, testCaseHint)
sort.Sort(sortedStringList(tt.preStopRuns))