Skip to content
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

Exec command args seem to be truncated in some cases #113

Open
sbrunk opened this issue Oct 11, 2021 · 6 comments
Open

Exec command args seem to be truncated in some cases #113

sbrunk opened this issue Oct 11, 2021 · 6 comments

Comments

@sbrunk
Copy link

sbrunk commented Oct 11, 2021

I'm running into a weird issue with the exec function where using certain shell operators seem to cause a truncation of the remaining input. I.e. using &&, || or ; in seems to remove all commands coming after the respective operator.

How to reproduce:

kubectl run debian --image debian -- sleep 9999

Then in Ammonite run:

@ import $ivy.`com.goyeau::kubernetes-client:0.8.0`
@ import cats.effect.IO
import com.goyeau.kubernetes.client._
import org.typelevel.log4cats.Logger
import org.typelevel.log4cats.slf4j.Slf4jLogger
import java.io.File
import scala.concurrent.ExecutionContext
import cats.effect.unsafe.implicits.global

implicit val logger: Logger[IO] = Slf4jLogger.getLogger[IO]

val kubernetesClient =
  KubernetesClient[IO](KubeConfig.fromFile[IO](new File(s"${System.getProperty("user.home")}/.kube/config")))

val r = kubernetesClient.use(_.pods.namespace("default").exec("debian", command=Seq("sh", "-c", "echo foo && echo bar"))).unsafeToFuture

@ println(new String(r.value.head.get._1(1).data))
// foo

It seems like echo bar is never executed.

kubectl exec for comparison returns the expected output:

kubectl exec debian -- sh -c "echo foo && echo bar"
foo
bar
@sbrunk
Copy link
Author

sbrunk commented Oct 11, 2021

One perhaps interesting observation is that http4s produces a a slightly different url encoding than kubectl:

@ execRequest("debian", Seq("sh", "-c", "echo a && echo b"), None).toString 
res80: String = "WSRequest(ws://localhost:8001/api/v1/namespaces/default/pods/debian/exec?stdin=false&stdout=true&stderr=true&tty=false&command=sh&command=-c&command=echo%20a%20%26%26%20echo%20b,Headers(Sec-WebSocket-Protocol: v4.channel.k8s.io),POST)"
kubectl exec -v=9 debian -- sh -c "echo a && echo b"
...
I1011 21:26:07.306205 1773178 round_trippers.go:435] curl -v -XPOST  -H "X-Stream-Protocol-Version: v4.channel.k8s.io" -H "X-Stream-Protocol-Version: v3.channel.k8s.io" -H "X-Stream-Protocol-Version: v2.channel.k8s.io" -H "X-Stream-Protocol-Version: channel.k8s.io" -H "User-Agent: kubectl/v1.22.2 (linux/amd64) kubernetes/8b5a191" 'https://127.0.0.1:45817/api/v1/namespaces/default/pods/debian/exec?command=sh&command=-c&command=echo+a+%26%26+echo+b&container=debian&stdin=true&stdout=true&tty=true'
...

http4s: command=echo%20a%20%26%26%20echo%20b
kubectl: command=echo+a+%26%26+echo+b

So we have percent encoding vs. plus sign for spaces. It might be interesting to replicate the kubectl encoding with a websocket connection (kubectl uses SPDY) to see if that makes a difference.

@sbrunk
Copy link
Author

sbrunk commented Oct 11, 2021

I did a quick hacky experiment and the different url encoding does not seem to be related to the issue.

@sbrunk
Copy link
Author

sbrunk commented Oct 16, 2021

Adding @novakov-alexey because you worked on that part of the code lately in #99 so perhaps you have a clue.

@novakov-alexey-zz
Copy link
Contributor

novakov-alexey-zz commented Oct 17, 2021

Hi @sbrunk , yes, I know about this issue. I could not solve it when I was implementing exec functionality. You are also right that http4s is encoding url a bit differently than Kubectl. I tried to align http4s with Kubectl, but it did not help back then. My guess it is something with Http4s or jdkWebSocketClient. If you have any other ideas we can try to fix it.
Current workaround is to split commands into several exec calls.

@sbrunk
Copy link
Author

sbrunk commented Oct 17, 2021

Thanks for confirming @novakov-alexey. I ended up using the workaround to split into several exec calls for now as you've also suggested.

@novakov-alexey-zz
Copy link
Contributor

One more trick is to use uploadFile API to upload a shell script and call it as a second step via exec. It can be useful, in case you want to open fewer web-socket connections.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants