Skip to main content
Skip table of contents

Step 3 of 5: Container Service Commands

Goal

In this step, you will learn how to create a new Command and attach it to a registered Docker Image. You will also try launching a couple of simple Commands using the XNAT REST API, via Swagger.

The XNAT Container Service uses a Command object to store information about how to launch Docker containers from images. This will perform the same role as the docker run command seen in Part 1 of this practical. When we ran docker run, we provided two main arguments: the name of the image that was the base for our container, and the command to run in the container.

To make a Command, we need the id of a Docker Image that has been registered with XNAT, and a string called the run-template. The Image id we will use is the Image we registered in Step 2 (it very probably has an id=1), and it tells docker which image will be the base for containers started from this Command. The run-template parameter defines an execution string to be run on the Docker container, and it essentially says what command to run in the container.

Define a command

We will POST to the /xapi/commands endpoint the following JSON:

XML
{
    "type": "docker-image",
    "name": "Hello world",
    "description": "Echos Hello World in Ubuntu",
    "docker-image": {"id": 1},
    "run-template": ["/bin/sh", "-c", "echo Hello World"]
} 

Tip

As shown above, the value of the docker-image.id field is 1. If you followed along with the instructions in Step 2, 1 is the ID of the Docker Image you created in that step. If you did things slightly differently, or you want to use a different Docker Image ID, you can change the value from 1 to some other Image ID.

 

  1. Return to the XNAT Swagger main page.
  2. Expand the command-rest-api item, and the POST /xapi/commands item.
  3. Copy the JSON above, and paste it into the command field. 
  4. Press the "Try it out!" button. Note the response value, which is the ID of the Command that was just created.

In this example:

  • The value docker-image.id=1 defines the particular registered Docker Image to use.
  • The value of run-template=["/bin/sh", "-c", "echo Hello World"] will be executed when XNAT starts a container using this Command.
  • The command id in the above screenshot is returned in the Response Body. If this is your first time creating a Command on this machine, your Command id will likely be 1.

Tip

If the response body looks more like a full web page than the value you were expecting, you are probably being redirected to the XNAT login page and will need to reload and authenticate before continuing.

 

Launch your command

Commands will usually be executed by XNAT as part of an ACE (Action/Context Execution), which allows the Command to use values and files from XNAT objects (sessions, subjects, scans, etc.) However, you are able to execute a command on its own. You won't be able to automatically fill in any information from XNAT, but in the case of the command defined above we don't need anything from XNAT, so that's fine.

  1. Return to the XNAT Swagger page.
  2. Expand command-rest-api, and POST /xapi/commands/{id}/launch.
  3. Enter 1 for the id parameter (or whatever response you received when you created the Command in the last step).
  4. Enter {} for the context parameter. (Swagger thinks this is required when it really isn't, so to satisfy Swagger we send in a blank object.)
  5. Press the "Try it out!" button.



You should receive a 200 Response Code, indicating there were no problems. The Response Body is the id of the docker container that was just executed. Note the value of the container id, so we can use it later.

We can see that the docker container executed our echo Hello World by inspecting its logs. However, we haven't yet written the REST API to get the logs from Docker (but it is coming). To see the logs, open a terminal, and navigate to your xnat-workshop-vms directory. Execute the following commands (replacing the <container id> string with the response you got back from XNAT a moment ago):

CODE
you@local-machine:xnat-workshop-vms$ ./run xnat-31 ssh
xnat@xnat-31:~$ docker logs <container id>
Hello World

We see there that the Command, which just ran  echo Hello World as we defined in the run-template, ran successfully. (We also see the handy Docker feature that the containers record their stdout and stderr for you to inspect later.)

Tip

A short-form <container id> is also accessible via Docker command line interface, if you did not record the response from XNAT when you launched the Command.

  • Run docker ps -a from your SSH prompt (xnat@xnat-31:~$)
  • Note the CONTAINER ID of the most recently exited container

 

Commands with variables

Now we know we can run Commands. But the Command we ran was boring, and just does the same thing every time. Let's make a new Command, this time using a variable that can be set when we execute it.

  1. Return to the XNAT Swagger main page.
  2. Expand the command-rest-api item, and the POST /xapi/commands item.
  3. Enter the following JSON into the command field:

    CODE
    {
        "type": "docker-image",
        "name": "echo with variable",
        "description": "Echos a message in Busybox",
        "docker-image": {"id": 1},
        "run-template": ["/bin/sh", "-c", "echo #message#"],
        "variables": [
            {
                "name": "message",
                "description": "The message to echo",
                "required": true,
                "value": "Hello XNAT"
            }
        ]
    }


    (Again, if your docker-image has a different id not equal to 1, use yours as the value of docker-image.id)

  4. Press the "Try it out!" button.

 

Once again, the Response Body value is your command id, which you should note for the next steps.

But let's pause for a moment to look at the JSON we just posted. We changed the run-template, which used to be ["/bin/sh","-c","echo Hello World"], and now is ["/bin/sh","-c","echo #message#"]. We also added a variables section, with one variable with name message

When we go to launch this Command, XNAT will fill out all the template strings in run-template, which look like #some-variable-name# by filling in the value from the variable named some-variable-name. We defined a default value="Hello XNAT", but if we send in another value when we execute the Command that will be used instead.

Now let's launch the Command.

  1. Return to the XNAT Swagger page.
  2. Expand command-rest-api, and POST /xapi/commands/{id}/launch.
  3. Enter 2 for the id parameter (or whatever response you received when you created the Command in the last step).
  4. Enter {"message":"Sup, XNAT?"} in the context field.
  5. Press the "Try it out!" button.

Copy the response body, and use it as <container id> in the following command (entered in the xnat-31 VM):

BASH
xnat@xnat-31:~$ docker logs <container id>
Sup, XNAT?

 

You can try entering other messages, and your container will dutifully echo them out.

 

In this step, you've seen how to define and launch XNAT commands. These commands bind registered Docker images with a run-template, templatized with variables. This binding enables XNAT-aware container execution using Actions, which we'll explore next.

Next step: Actions

 

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.