-
Notifications
You must be signed in to change notification settings - Fork 144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add lifecycle validation #558
add lifecycle validation #558
Conversation
Before 'start', we have 'create' operation, so I think this spec means:
How about make a testcase like this:
so when 'create', the $bundle/$rootfs/output should be empty, |
I think |
2f516d4
to
7c18974
Compare
According to the description of lifecycle, I have determined the order of calls for each part: create -> start -> prestart -> process -> poststart -> delete -> poststop The code is updated according to this call order. |
validation/lifecycle.go
Outdated
return err | ||
} | ||
if string(outputData) != "" { | ||
return errors.New("Wrong call") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not quite sure what to say about this type of error. Any suggestions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not quite sure what to say about this type of error.
The associated specerror
entries start around here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depending on what is read, the specific error is different. It would be very troublesome to be accurate to every error condition. So instead of making a further distinction, I want to output the error directly.
Do you think it is necessary to distinguish between each error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, each error should explicitly reflect the relevant 'specerror'.
validation/lifecycle.go
Outdated
t.Header(0) | ||
|
||
prestart := rspec.Hook{ | ||
Path: "/usr/bin/prestart", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where does /usr/bin/prestart
come from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About this path
, I thought it was created automatically when added.
Maybe this idea is wrong.
Do you have any suggestions for the path
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have any suggestions for the
path
?
The echo on our BusyBox tarball?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm writing a demo to show my idea, I'll link to you soom.
Following your idea, I made some changes: https://github.com/liangchenye/ocitools/blob/gotest/validation/lifecycle.go
About the 'Wrong Error", I suggest we may split the lifecycle.go to 'prestart.go', 'poststart.go' and the etc. Each hook has multiply spec errors, it will make it easier to maintain and cover all the errors. How do you think ? @q384566678 |
On Wed, Jan 31, 2018 at 07:39:28PM -0800, 梁辰晔 (Liang Chenye) wrote:
1. using 'sh' and 'echo' in the bundle
This general approach looks good to me, but you'll want to use Go's
filepath.Join to compose the paths for Windows compat. And we'll need
future work to ensure we have a usable tarball for the host platform
that includes ‘sh’, ‘echo’, and anything else we need.
About the 'Wrong Error", I suggest we may split the lifecycle.go to
'prestart.go', 'poststart.go' and the etc. Each hook has multiply
spec errors, it will make it easier to maintain and cover all the
errors.
This sounds like a good idea to me. Common code can always go into a
helper, although I'm not sure how much overlap there will be.
|
@liangchenye That sounds good. I'll update patch in this way. Thank you for your advice. |
1c6387c
to
4ad25ac
Compare
updated, @liangchenye @wking PTAL. |
validation/poststart.go
Outdated
}, | ||
PostCreate: func(r *util.Runtime) error { | ||
outputData, err := ioutil.ReadFile(output) | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is expected to get an 'err', since the 'output' will not exist.
validation/poststart.go
Outdated
return err | ||
} | ||
switch string(outputData) { | ||
case "": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should not happen, we can move it to 'default' part.
validation/poststart.go
Outdated
switch string(outputData) { | ||
case "": | ||
return nil | ||
case "post-start called\n": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can make it simpler:
if strings.Contains(string(outputData), "post-start") {
return specerror.NewError(specerror.PoststartTimin
} else if strings.Contains(string(outputData), "process") {
return specerror.NewError(specerror.ProcNotRunAtResRequest)
}
validation/poststart.go
Outdated
PreDelete: func(r *util.Runtime) error { | ||
outputData, err := ioutil.ReadFile(output) | ||
if err != nil { | ||
return err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also
return fmt.Errorf("%v\n%v", specerror.NewError(specerror.PoststartHooksInvoke,
I commented in prestart.go and it misses one case:
|
validation/poststop.go
Outdated
}, | ||
PostCreate: func(r *util.Runtime) error { | ||
outputData, err := ioutil.ReadFile(output) | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to 'poststart.go', we should get an error: the output file is not exist.
validation/prestart.go
Outdated
}, | ||
PostCreate: func(r *util.Runtime) error { | ||
outputData, err := ioutil.ReadFile(output) | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same, should get an error.
validation/prestart.go
Outdated
return err | ||
} | ||
switch string(outputData) { | ||
case "": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
""
could merge with default
validation/poststop.go
Outdated
return err | ||
} | ||
switch string(outputData) { | ||
case "": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a part of 'default'
validation/poststart.go
Outdated
return err | ||
} | ||
switch string(outputData) { | ||
case "": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a part of 'default'
validation/prestart.go
Outdated
return err | ||
} | ||
switch string(outputData) { | ||
case "": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
part of 'default'
validation/prestart.go
Outdated
return specerror.NewError(specerror.PrestartTiming, fmt.Errorf("Pre-start hooks MUST be called after the `start` operation is called"), rspec.Version) | ||
case "process called\n": | ||
return specerror.NewError(specerror.ProcNotRunAtResRequest, fmt.Errorf("The user-specified program (from process) MUST NOT be run at this time"), rspec.Version) | ||
case "pre-start called\nprocess called\n", "process called\npre-start called\n": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this, change
case "pre-start called\n"
to
strings.Contain
validation/poststop.go
Outdated
return err | ||
} | ||
switch string(outputData) { | ||
case "": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a part of default
Same to other hooks.
|
92b6907
to
70a423b
Compare
3c3b7d6
to
8dca66d
Compare
@liangchenye @wking updated, PTAL. |
1c2ac39
to
32fe314
Compare
|
I saw another problem in the test code, the process 'output' filepath is wrong, it is already running inside the container.
|
validation/poststart.go
Outdated
} | ||
|
||
g.AddPostStartHook(poststart) | ||
g.SetProcessArgs([]string{"sh", "-c", fmt.Sprintf("echo 'process called' >> %s", output)}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to:
g.SetProcessArgs([]string{"sh", "-c", fmt.Sprintf("echo 'process called' >> %s", "/output")})
} | ||
return nil | ||
}, | ||
PreDelete: func(r *util.Runtime) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest we can add
util.WaitingForStatus(*r, util.LifecycleStatusStopped, time.Second * 10, time.Second)
'start' will return immediately, although 'echo' runs fast, but we are not sure how many time it costs. (for example, in runc/cc/Kata project)
PostCreate: func(r *util.Runtime) error { | ||
outputData, err := ioutil.ReadFile(output) | ||
if err == nil { | ||
if strings.Contains(string(outputData), "post-start called") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I always got it in 'runc'!
validation/prestart.go
Outdated
} | ||
|
||
g.AddPreStartHook(prestart) | ||
g.SetProcessArgs([]string{"sh", "-c", fmt.Sprintf("echo 'process called' >> %s", output)}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same, the output is wrong.
validation/prestart.go
Outdated
return nil | ||
}, | ||
PreDelete: func(r *util.Runtime) error { | ||
outputData, err := ioutil.ReadFile(output) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same, I suggest to add 'Wait.."
PostCreate: func(r *util.Runtime) error { | ||
outputData, err := ioutil.ReadFile(output) | ||
if err == nil { | ||
if strings.Contains(string(outputData), "pre-start called") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I always get this in 'runc'.
case "process called\n": | ||
fmt.Fprintln(os.Stderr, "WARNING: The poststart hook invoke fails") | ||
return nil | ||
case "post-start called\nprocess called\n": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since 'post-start' runs in 'create', the sequence here is wrong.
validation/poststop.go
Outdated
} | ||
|
||
g.AddPostStopHook(poststop) | ||
g.SetProcessArgs([]string{"sh", "-c", fmt.Sprintf("echo 'process called' >> %s", output)}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same, wrong output
Report an issue in 'runc' project: opencontainers/runc#1710. |
Signed-off-by: Zhou Hao <[email protected]>
32fe314
to
09ddc02
Compare
I am going to add a validation of the lifecycle, the specific norms are as follows:
But I can not confirm the specific call state, so for the moment I'm just verifying that the relevant command has not been called.
This is just a preliminary idea. Lifecycle validation also need more work, any comments welcome. Or you can write a new patch.
Signed-off-by: Zhou Hao [email protected]