-
Notifications
You must be signed in to change notification settings - Fork 142
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
Fix #556 #557
Fix #556 #557
Conversation
ae63341
to
56857d8
Compare
56857d8
to
b483dc1
Compare
This PR does two things:
It is similar to So if this approach is useful, we can merge 'RuntimeInsideValidate', ‘RuntimeOutsideValidate' and 'RuntimeLifecycleValidate' into one.
|
b483dc1
to
78f41b5
Compare
validation/pidfile.go
Outdated
t.Header(0) | ||
|
||
var lifecycle util.LifecycleFuncs | ||
tempFile, err := ioutil.TempFile("", "oci-pidfile") |
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.
This approach (using an empty but already existing PID file) seems strange to me. We may want to update the CLI spec to specifically address this case and keep this test, but I think a more traditional test would be to use a temp directory with a --pid-file
path that is a direct child of that temp directory (so the target path does not exist when create
is 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.
It is not an existing PID file, it is also a new temp file, similar to using TempDir + 'pid'.
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 not an existing PID file, it is also a new temp file, similar to using TempDir + 'pid'.
The TempFile
docs say it creates the file. TempDir
+ "pid"
would not.
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.
Got it.
validation/pidfile.go
Outdated
util.Fatal(err) | ||
} | ||
tempPidFile := tempFile.Name() | ||
lifecycle.Setup = 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.
Instead of initializing lifecycle
and then filling in these properties, it might be more idiomatic to use:
lifecycle := util.LifecycleFuncs{
Setup: func(…) error {
…
},
PreStart: …,
PostStart: …,
}
validation/pidfile.go
Outdated
defer os.Remove(tempPidFile) | ||
|
||
lifecycle.PreStart = func(r *util.Runtime) error { | ||
pidData, err := ioutil.ReadFile(tempPidFile) |
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 think we want a PostCreate
slot (maybe instead of the PreStart
slot?). We can run the --pid-file
test with create
/ kill
/ delete
without involving start
.
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.
+1, 'PostCreat'e is better, 'Prestart' might also be confusing,
validation/pidfile.go
Outdated
} | ||
|
||
lifecycle.PostStart = func(r *util.Runtime) error { | ||
time.Sleep(1 * time.Second) |
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.
What's this about?
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.
Waiting for the container to stop, or we cannot delete it.
There should be a better function to waiting for the status change.
validation/pidfile.go
Outdated
return nil | ||
} | ||
|
||
lifecycle.PostStop = 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.
Isn't this the default already? I don't think we need this line.
validation/pidfile.go
Outdated
lifecycle.PostStop = nil | ||
|
||
g := util.GetDefaultGenerator() | ||
g.SetProcessArgs([]string{"ls"}) |
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'd rather use:
g.Spec().Process = nil
and skip start
.
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.
'runc' has a bug: if the 'Process' is nil, runc crashes.
Besides this, 'runc' does not follow the CLI spec, it applies the 'process args' when create a container.
I add a test to change the 'process args' in PostCreate, in theory, runc should execute the new args, but it does not.
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.
'runc' has a bug: if the 'Process' is nil, runc crashes
create
crashes? That would be a bug.
I add a test to change the 'process args' in PostCreate, in theory, runc should execute the new args, but it does not.
No, the runtime must ignore any post-create config changes, so runc
is fine on that point.
validation/util/container.go
Outdated
@@ -56,14 +57,21 @@ func (r *Runtime) SetID(id string) { | |||
r.ID = id | |||
} | |||
|
|||
// SetPidFile sets the pid file | |||
func (r *Runtime) SetPidFile(pidFile string) { |
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.
PidFile
is already public. I don't think we need a setter.
@@ -146,23 +154,32 @@ func (r *Runtime) State() (rspecs.State, error) { | |||
} | |||
|
|||
// Delete a container | |||
func (r *Runtime) Delete() error { | |||
func (r *Runtime) Delete() ([]byte, 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.
Why are we returning stderr
? You don't seem to consume this new value anywhere.
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 use this to debug why 'Delete' fails.
The 'time.Sleep' line is coming from this.
validation/util/test.go
Outdated
} | ||
} | ||
|
||
stderr, err = r.Start() |
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 think we'll want a flag to toggle whether we call Start
or not.
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.
So something like this
func RuntimeLifecycleValidate(g *generate.Generator, lifecycle *LifecycleFuncs, actions LifecycleAction) {
...
if actions & LifeCycleCreate {
stderr, err := r.Create()
}
...
if actions & LifeCycleStart {
stderr, err = r.Start()
}
...
}
78f41b5
to
9df90d8
Compare
Two issues were found, but I think they could be solved in other PRs.
PTAL @wking @q384566678 @Mashimiao |
9df90d8
to
08d0bd1
Compare
validation/pidfile.go
Outdated
util.Fatal(err) | ||
} | ||
tempPidFile := filepath.Join(tempDir, "pidfile") | ||
defer os.RemoveAll(tempDir) |
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.
nit: I'd rather swap the order of these two lines to get the cleanup defer
right after the TempDir
error check. filepath.Join
cannot error, but having the defer
set as early as possible would give me warm fuzzy feelings ;).
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.
OK, I'll update it.
) | ||
|
||
var lifecycleStatusMap = map[string]LifecycleStatus{ | ||
"creating": LifecycleStatusCreating, |
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.
Or these could just be strings:
type LivecycleStatus string
const (
LifecycleStatusCreating = "creating"
…
)
and then you cast with LifecycleStatus(state.Status)
. I don't see a need for indirection through an integer.
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.
An 'integer' is useful when we expect to have multiple statuses. For example, if we want to delete a container, we expected to have 'created' or 'stopped' status. So we can 'WaitingForStatus(Created|Stopped)'.
validation/util/test.go
Outdated
@@ -184,3 +248,74 @@ func RuntimeOutsideValidate(g *generate.Generator, f AfterFunc) error { | |||
} | |||
return nil | |||
} | |||
|
|||
// RuntimeLifecycleValidate validates runtime lifecycle. | |||
func RuntimeLifecycleValidate(g *generate.Generator, lifecycle *LifecycleFuncs, actions LifecycleAction) 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 don't see a need to split funcs from actions. Can we rename LifecycleFuncs
to LifecycleConfig
(or just Lifecycle
?) and add an Actions
property?
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.
+1 for this
validation/util/test.go
Outdated
} | ||
} | ||
|
||
if lifecycle != nil && lifecycle.PostStop != 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.
I think anything running after Delete
should be PostDelete
. This PR currently seems to handle stop
and delete
in one step (or maybe it is never intended to call stop
and instead waits for the container to stop on its own?), but calling this setting PostDelete
makes sense regardless of an explicit stop or not.
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.
So all the embedded functions should have different new, I'll update it too.
I prefer calling the 'stop' in the related test cases, for example, if we want to test 'kill'.
We can add test codes in the 'PreDelete'. (PreDelete is better than PreStop)
08d0bd1
to
a7f123b
Compare
Fixes opencontainers#556 Signed-off-by: Liang Chenye <[email protected]>
a7f123b
to
5e8b51e
Compare
Updated by using lifecycleConfig (merge funcs and actions), now the funcs are symmetrical: PreCreate/PostCreate, PreDelete/PostDelete |
1 similar comment
return nil | ||
}, | ||
PreDelete: func(r *util.Runtime) error { | ||
return util.WaitingForStatus(*r, util.LifecycleStatusCreated, time.Second*10, time.Second*1) |
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 shouldn't need this, because a container must be created before create
returns. Maybe a runc bug?
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.
runc
does not implement 'creating' lifecycle ,
it is always 'created' or 'fails'.
From the spec, it should be like this:
- user run
runX create x
- user run
runX status x
it should be 'creating' (assuming the creating takes a long time).
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.
runc
does not implement 'creating' lifecycle...
That's definitely a bug. And there's also some CLI spec wording about create
's exit timing. I think we can drop this, and I'll file a runc patch.
The runtime-spec defines a 'creating' status [1] and requires the 'create' operation to finish creating the container [2,3]. Our command line API also requires the 'create' command to block until creation completes: Callers MAY block on this command's successful exit to trigger post-create activity. runc does not support 'creating' yet [4], and it seems to return from 'create' before having quite finished (or we wouldn't have needed the code I'm removing in this commit). However, both of those are runc problems. These tests are about validating spec compliance, not about working around runc's issues, so remove the crutches. [1]: https://github.com/opencontainers/runtime-spec/blame/v1.0.1/runtime.md#L19 [2]: https://github.com/opencontainers/runtime-spec/blame/v1.0.1/runtime.md#L54 [3]: https://github.com/opencontainers/runtime-spec/blame/v1.0.1/runtime.md#L101 [4]: opencontainers#557 (comment) Signed-off-by: W. Trevor King <[email protected]>
The runtime-spec defines a 'creating' status [1] and requires the 'create' operation to finish creating the container [2,3]. Our command line API also requires the 'create' command to block until creation completes: Callers MAY block on this command's successful exit to trigger post-create activity. runc does not support 'creating' yet [4], and it seems to return from 'create' before having quite finished (or we wouldn't have needed the code I'm removing in this commit). However, both of those are runc problems. These tests are about validating spec compliance, not about working around runc's issues, so remove the crutches. [1]: https://github.com/opencontainers/runtime-spec/blame/v1.0.1/runtime.md#L19 [2]: https://github.com/opencontainers/runtime-spec/blame/v1.0.1/runtime.md#L54 [3]: https://github.com/opencontainers/runtime-spec/blame/v1.0.1/runtime.md#L101 [4]: opencontainers#557 (comment) Signed-off-by: W. Trevor King <[email protected]>
The runtime-spec defines a 'creating' status [1] and requires the 'create' operation to finish creating the container [2,3]. Our command line API also requires the 'create' command to block until creation completes: Callers MAY block on this command's successful exit to trigger post-create activity. runc does not support 'creating' yet [4], and it seems to return from 'create' before having quite finished (or we wouldn't have needed the code I'm removing in this commit). However, both of those are runc problems. These tests are about validating spec compliance, not about working around runc's issues, so remove the crutches. [1]: https://github.com/opencontainers/runtime-spec/blame/v1.0.1/runtime.md#L19 [2]: https://github.com/opencontainers/runtime-spec/blame/v1.0.1/runtime.md#L54 [3]: https://github.com/opencontainers/runtime-spec/blame/v1.0.1/runtime.md#L101 [4]: opencontainers#557 (comment) Signed-off-by: W. Trevor King <[email protected]>
Signed-off-by: Liang Chenye [email protected]