-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
podman play should honour both ENTRYPOINT and CMD from image #8666
Conversation
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: cruwe The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
I'm not opposed but we should make this conditional, so it's not a breaking change. Maybe a |
I am starting to wonder: Am I missing some important context or intent which I do not know about? |
I think I now got the intent. I am not satisfied with the verbosity, but I think the code should closely mirror the spec to prevent misunderstandings. What is the project's position on duplication vs readability? |
I am a firm believer in readability being the first consideration (I am admittedly biased by the amount of code review I do 😄 ) |
pkg/specgen/generate/kube/kube.go
Outdated
s.Command = nil | ||
s.Command = append(s.Command, containerYAML.Args...) |
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 these two lines are easier to read when combined into the following line:
s.Command = containerYAML.Args
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.
put a comment there to clarify the intent
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.
ah, got it ... yes, you're right
pkg/specgen/generate/kube/kube.go
Outdated
s.Command = nil | ||
s.Command = append(s.Command, containerYAML.Args...) |
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 these two lines are easier to read when combined into the following line:
s.Command = containerYAML.Args
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.
likewise
and code need go fmt |
that I do not get. I did and the IDE does at any commit. Nothing changed. Could you point me in the direction? |
38e0811
to
60dd501
Compare
// doc https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#notes | ||
if len(containerYAML.Args) != 0 { | ||
|
||
if len(containerYAML.Command) == 0 && len(containerYAML.Args) == 0 { |
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.
btw, I am pretty sure that the initialization with []string{}
from L109 is not necessary. It runs fine here without and s.ContainerBasicConfig.Command
and .Entrypoint
, which in theory should suffer from the same problem, are initialized just fine.
pkg/specgen/generate/kube/kube.go
Outdated
s.Command = nil | ||
s.Command = append(s.Command, containerYAML.Args...) |
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.
ah, got it ... yes, you're right
you could right click the changed files., and choose the gofmt,or use |
Without exerting undue pressure, I'd like to point out that this PR fixes a regression: Take for instance This behaviour is shown by We use the Please, tell me what I can do to have the process sped up. Thank you very much for your time and consideration. |
you cloud see this for more detail : https://github.com/containers/podman/pull/8666/checks?check_run_id=1529080539 your code need to go fmt, and git commits need to rebase to 1 commit. |
60dd501
to
e290287
Compare
@zhangguanzhang : Thanks! |
e290287
to
ec70d33
Compare
I am willing to work on the failing tests. I am not particularly fluent in golang and absolutely new to ginko, so I'll definitely need some guidance. However, before I start working, could we reach consensus on the general idea to honour entrypoint and command from the image and be strict about the the k8s specs? @zhangguanzhang , @mheon, could you help me reaching that consensus? |
This behavior cannot be default, because it would be a breaking chance from the way things are now. I am OK with doing it, but it will need to be gated behind a flag. |
This did cause the yaml I exported using the |
Hi, I already feared that there might be a severe misunderstanding present here, perhaps on my part, I do not know. I am not trying to implement a feature here, I observed an undocumented breaking change, assumed that to be an unintended side-effect of some major refactoring and attempted, not least because I am/was relying on the feature, to come up with a fix. Consider the following pod definition: ---
apiVersion: v1
kind: Pod
metadata:
name: try
spec:
containers:
- name: try
image: docker.io/library/redis:6 The image comes with "pre-packaged" On podman v2.1 (please disregard the naming of my binaries), it starts just fine. The version is $ ./bin/podman-v2.1 version
Version: 2.1.1
API Version: 2.0.0
Go Version: go1.13.8
Git Commit: 9f6d6ba0b314d86521b66183c9ce48eaa2da1de2
Built: Tue Dec 15 19:28:07 2020
OS/Arch: linux/amd64 and, the container starting fine, I have nothing to tell here. On podman v2.2, it constantly crashes (without any logs, which I would supply otherwise), because the new On Version: 2.2.1
API Version: 2.1.0
Go Version: go1.13.8
Git Commit: a0d478edea7f775b7ce32f8eb1a01e75374486cb
Built: Tue Dec 15 19:24:20 2020
OS/Arch: linux/amd64
$ ./bin/podman-v2.2 inspect try_pod-try \
| jq '.[] | {"args": .Args, "cmd": .Config.Cmd, "entrypoint": .Config.Entrypoint }'
{
"args": [
"docker-entrypoint.sh"
],
"cmd": [
"docker-entrypoint.sh"
],
"entrypoint": "docker-entrypoint.sh"
} That certainly can never start any redis. So, I still do not understand if this behaviour is really intentional (please bear with me should I lack understanding). Is the new behaviour intentional and canonical? Then, I'd politely ask to mention a breaking change in the Changelogs, still politely, even if I needlessly spent hours chasing my crashing pods in my testing environment. In addition, it should then be documented that users MUST pass If it is not intended to behave different than the k8s spec specifies, then I fail (perhaps I am thinking wrong here?) to understand why a correct behaviour should be gated behind a flag, when the incorrect behaviour is the default. I hope I did not let emotions run here, I certainly do not want to offend. I (still?) firmly believe the behaviour of v2.2 is buggy and I am ready to stand corrected should someone explain to me disregarding In any case, thank you for your patience. (I am on CET, so I will not be active any more for my instance of today.) |
OK, this is not the impression I got from the initial PR - sorry. Yes, we did do a major rewrite of If this is a regression, we need a test to catch it in the future; would you be willing to write one? |
Hi, there already are tests, which do not catch at least one case described in the k8s spec. I'll give it a try and try to work in parallel to what and how @zhangguanzhang solved it in July. Cheers! |
64880f3
to
c778388
Compare
try ro change https://github.com/containers/podman/blob/master/test/e2e/play_kube_test.go#L1248-L1267 to: It("podman play kube deployment more than 1 replica test correct command", func() {
var i, numReplicas int32
numReplicas = 5
deployment := getDeployment(withReplicas(numReplicas))
err := generateKubeYaml("deployment", deployment, kubeYaml)
Expect(err).To(BeNil())
kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube.ExitCode()).To(Equal(0))
podNames := getPodNamesInDeployment(deployment)
correctCmd := "[" + strings.Join(defaultCtrArg, " ") + "]"
correctEntrypoint := defaultCtrCmd
for i = 0; i < numReplicas; i++ {
inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&podNames[i]), "--format", "'{{ .Config.Cmd }}'"})
inspect.WaitWithDefaultTimeout()
Expect(inspect.ExitCode()).To(Equal(0))
Expect(inspect.OutputToString()).To(Equal(correctCmd))
inspect = podmanTest.Podman([]string{"inspect", getCtrNameInPod(&podNames[i]), "--format", "'{{ .Config.Entrypoint }}'"})
inspect.WaitWithDefaultTimeout()
Expect(inspect.ExitCode()).To(Equal(0))
Expect(inspect.OutputToString()).To(Equal(correctEntrypoint))
}
}) by the way,maybe not need so much tests |
test/e2e/play_kube_test.go
Outdated
if err != nil { | ||
panic(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.
if err != nil { | |
panic(err) | |
} | |
Expect(err).To(BeNil()) |
test/e2e/play_kube_test.go
Outdated
if err != nil { | ||
panic(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.
if err != nil { | |
panic(err) | |
} | |
Expect(err).To(BeNil()) |
and need rebase the commits to one commit |
c778388
to
06fabdb
Compare
@zhangguanzhang : I changed the deployment test to test replica count. The idea is, that pod structure has already been tested at pod level, so at deployment level, I suggest to test what's new / different there and that's replica count. |
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 did cause the yaml I exported using the
podman generate kube
command to be unable to deploy using thepodman play kube
command.
@daiaji: Could you give an example? I'd like to have a look.
test/e2e/play_kube_test.go
Outdated
@@ -1349,6 +1358,8 @@ spec: | |||
}) | |||
|
|||
// Deployment related tests | |||
// FIXME: these just double the pod tests, replacing pod with deplotment | |||
// FIXME: what's the point? |
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.
The deployment tests just mirror the tests for pods. Are these really necessary? I'd just omit them - is there any case why a deployment (containing a pod) should behave differently than an pod?
test/e2e/play_kube_test.go
Outdated
Expect(containerCmd).NotTo(Equal(imgCmd)) | ||
|
||
Expect(containerEntrypoint).To(Equal(strings.Join(overrideCmd, " "))) | ||
Expect(containerCmd).To(Equal(nilArray)) |
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 nit
Expect(containerCmd).To(Equal(nilArray)) | |
Expect(len(containerCmd)).To(Equal(0)) |
/retest |
if len(containerYAML.Command) == 0 && len(containerYAML.Args) == 0 { | ||
s.Entrypoint = imageData.Config.Entrypoint | ||
s.Command = imageData.Config.Cmd | ||
} | ||
|
||
if len(containerYAML.Command) != 0 && len(containerYAML.Args) == 0 { | ||
s.Entrypoint = containerYAML.Command | ||
s.Command = nil | ||
} | ||
|
||
if len(containerYAML.Command) == 0 && len(containerYAML.Args) != 0 { | ||
s.Entrypoint = imageData.Config.Entrypoint | ||
s.Command = containerYAML.Args | ||
} | ||
|
||
if len(containerYAML.Command) != 0 && len(containerYAML.Args) != 0 { | ||
s.Entrypoint = containerYAML.Command | ||
s.Command = containerYAML.Args | ||
} |
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.
Hi! can we boil this down to a simple "set entrypoint/command from imageData
and override from containerYAML
when set" ? I haven't seen this PR before I started fixing this and this would be my patch of this file: https://github.com/containers/podman/compare/master...bziemons:patch-kube-play-8428.patch
I also want to emphasize that the if imageData != nil && imageData.Config != nil {
above is probably there for a reason and accessing imageData.Config
without it is probably not a good idea.
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.
agree with @bziemons, line: 132,142 need the the imageData != nil && imageData.Config != 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.
Hi! can we boil this down to a simple "set entrypoint/command from
imageData
and override fromcontainerYAML
when set" ? I haven't seen this PR before I started fixing this and this would be my patch of this file: https://github.com/containers/podman/compare/master...bziemons:patch-kube-play-8428.patch
Yes, we can do that. It is functionally equivalent and less code, but it lacks the clarity in mirroring the k8s specs that I wished to express. I feel that your proposition warrants some line of comments to establish that link, but apart from that, I wouldn't complain.
I also want to emphasize that the
if imageData != nil && imageData.Config != nil {
above is probably there for a reason and accessingimageData.Config
without it is probably not a good idea.
I fear I lost the context here. Are you referring to L115 before setting s.WorkDir = imageData.Config.WorkingDir
? I did not notice that, but I supsect it is not necessary, because imageData
is populated with imageData, err := newImage.Inspect(ctx)
at L110. Any failure to get the imageData
returns there.
In addition, I cannot imagine how to start any container without having both imageData
and imageData.Config
. Accordingly, the corresponding check, if it really is necessary, is misplaced when setting single values and should be performed at the "global" level somewhar at libpod/image/image.go
, Inspect
or when examining the return value of it's invocation at L110.
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 also want to emphasize that the
if imageData != nil && imageData.Config != nil {
above is probably there for a reason and accessingimageData.Config
without it is probably not a good idea.
I fear I lost the context here
Ok, now I get it. That part, if it is really necessary, about which I am yet not sure, should error much higher in the chain.
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 agree with you and the if should have gotten a comment from its writer about why it is needed. Even if it isn't needed it wouldn't make sense to make the code more confusing about it (I know that wasn't your intention ;) ). Thanks for accepting my feedback though
06fabdb
to
950af8a
Compare
More specifically, - use both `ENTRYPOINT` and `CMD` from image when neither `command` nor `args` have been supplied the pod spec, - use the `command` and only the `command` when `command` has been passed in the pod spec, ignoring both `ENTRYPOINT` and `CMD` from the image, - run the `ENTRYPOINT` from the image with `args` from the pod spec when only `args` have been passed and - override both when both `command` and `args` are present in the spec. Necessarily, - adapt pod tests to test the k8s spec documented at the k8s web-docs, - remove assertions already tested at pod level from deployments and - shift focus to replica count when testing deployments. In passing, - remove unnecessary `s.Command` initialization. Signed-off-by: Christopher J. Ruwe <[email protected]>
950af8a
to
bcda8e9
Compare
An alternative fix is here #8807 (I totally didn't see this before implementing it, sorry if I have stepped on some toes,,,) |
Fine. I am really disappointed how this has been handled. |
@cruwe Thanks for your PR. I am sorry about the conflicting PRs. |
Assigning the entrypoint to
command
may be in line with the Kubernetescommand
andargs
pattern, but breaks normal behaviour when creating the container without passing any of those.I have WIPed this, because I am testing a larger deployment, am uneasy about what to find next and don't want to mess up history with one-liners