Execute commands with API and Websocket

Hello,
i try to use the Rancher API for execute some commands into a container. I get connected but i can’t send commands.

My workflow:

cURL command line:
curl -u “${CATTLE_ACCESS_KEY}:${CATTLE_SECRET_KEY}”
-X POST
-H ‘Accept: application/json’
-H ‘Content-Type: application/json’
-d ‘{“attachStdin”:true, “attachStdout”:true, “command”:["/bin/bash"], “tty”:true}’
http://rancher:8080/v1/projects/1a5/containers/1i332/?action=execute

Response:
{“id”:null,“type”:“hostAccess”,“links”:[],“actions”:[],“token”:“eyJhbGciOi…”,“url”:“ws://rancher:8080/v1/exec/”}

Connect to Socket with ws://rancher:8080/v1/exec/?token=eyJhbGciOi…

Response:
cm9vdEAyNmEyNjQ1NjYzYWQ6LyMg (Base64Decode output: root@26a2645663ad:/#)

It seems to work. After the connection is established to the Server, i want to execute some commands for example:
apt-get update
cd /test && echo “Hello World!” > file.txt

but my console get no response.

Tested Socket Clients:

  • Chrome Websocket Client
  • Dark WebSocket Terminal
  • PHP Library (composer textalk/websocket)

I don’t understand what I’m doing wrong. No solutions found in the docs.

Thanks for any help :slight_smile:

Hi,
even though it is a bit late, I had similar issues. Using the below groovy code I managed to get it to work. Hopefully this helps someone who was looking to get this to work. The methods getRancherDefaultEnvironmentKey and getFromRancherApi should be self-explanatory.

import groovy.json.JsonSlurper
import org.java_websocket.drafts.Draft_6455

def executeInsideContainer(String command, String containerNameContains){
    def defaultEnvironmentKey = getRancherDefaultEnvironmentKey()
    def containers = getFromRancherApi("/v2-beta/projects/${defaultEnvironmentKey}/containers")
    def containerId = containers.data.find { container -> container.name.contains(containerNameContains) }.id

    def executeUrl = rancherHostUrl + "/v2-beta/projects/${defaultEnvironmentKey}/containers/${containerId}/?action=execute"
    HttpURLConnection connection = (HttpURLConnection) executeUrl.toURL().openConnection()
    connection.setDoOutput(true)
    connection.setRequestMethod("POST")
    connection.setRequestProperty("Authorization", "Basic ${authString}")
    connection.setRequestProperty("Content-Type", "application/json")
    connection.setRequestProperty("Accept", "application/json")
    def data = '{"attachStdin":false, "attachStdout":false, "command":[' + command + '], "tty":false}'
    connection.outputStream << data
    if (connection.getResponseCode() == HttpURLConnection.HTTP_OK ||
        connection.getResponseCode() == HttpURLConnection.HTTP_ACCEPTED ||
        connection.getResponseCode() == HttpURLConnection.HTTP_CREATED) {
    } else {
        String response = (new InputStreamReader(connection.getErrorStream())).readLines().join(" ")
        println "POST URL: " + executeUrl
        throw new IOException("Error during POST request (ResponseCode ${connection.getResponseCode()}): " + response)
    }
    def responseBody = connection.getInputStream().readLines()
    JsonSlurper slurper = new JsonSlurper()
    def slurped = slurper.parseText(responseBody)
    def token = slurped.token
    def websocketUrl = slurped.url
    println "Making request to websocket: " + websocketUrl
    org.java_websocket.client.WebSocketClient mWs = new MyWebSocketClient( new URI( websocketUrl + "?token=" + token ), new Draft_6455(), null, 60)
    def connectionResult = mWs.connectBlocking()
    mWs.close()
    return connectionResult
}