Container Manager
Harpoon provides a way of requesting containers via a web server, called the container manager.
For example, you could have a config like:
---
images:
server:
context: false
commands:
- FROM python:3
- - ADD
- dest: /example_file
content: "hello there"
- CMD python -m http.server 4545
And then, using this config file as your configuration, run:
$ harpoon container_manager
By default, this will start the server on port 4545, see below for more information on the options to the container manager.
You can then request an image by doing something like:
$ curl -XPOST http://localhost:4545/start_container \
-HContent-Type:application/json \
-d '{"image": "server", "ports": [[0, 4545]]}'
Which will return something like:
{
"ports": {"4545": 32772},
"just_created": true,
"container_id": "73843d875d62cded348e1bba08ef8ba567d6f8a20feb078d8beb4170a9f85965"
}
This says that port 4545 in the container is mapped to port 32772 on your host.
And with that port, we can now say:
$ curl http://localhost:32772/example_file
hello there
If you do the start_container POST again, then it will reuse this same container and return the same response, but say “just_created: false”.
You can then either explicitly stop this container by saying:
$ curl -XPOST http://localhost:4545/stop_container \
-HContent-Type:application/json \
-d '{"image": "server"}'
Which will return an empty 204 response.
Or you can leave it and it’ll be cleaned up when you shut down the container manager.
You can shutdown the container manager by either ctrl-c’ing the process, or sending it a SIGTERM or by making a GET request to /shutdown:
$ curl http://localhost:4545/shutdown
When the container manager stops, any running containers will be stopped and removed from docker.
The last endpoint is /version which will return something like:
$ curl http://localhost:4545/version
harpoon 0.16.0
Locking containers
You can also lock access to a running container by specifying as such when you start the container, and then unlocking the container when you’re finished with it.
To do this, add "lock": true
to the /start_container
request:
$ curl -XPOST http://localhost:4545/start_container \
-HContent-Type:application/json \
-d '{"image": "server", "ports": [[0, 4545]], "lock": true}'
Then any subsequent /start_container
calls for that image will wait in turn
until you call /unlock_container
for that image:
$ curl -XPOST http://localhost:4545/unlock_container \
-HContent-Type:application/json \
-d '{"image": "server"}'
So if you start three /start_container
calls, then you’ll need three
/unlock_container
calls.
Container Manager Options
When you start the container manager, it takes in one positional argument that specifies how it starts and what port it serves on.
When you start the container manager without options, it’s the same as saying:
$ harpoon container_manager :4545
Which says start the container manager in the foreground and run it on port 4545.
You can also tell harpoon to start in the background by giving it a path to a file:
$ harpoon container_manager /path/to/file:4545
This will fork the process and write to /path/to/file
the port the manager
started on and the pid of the child:
<port>
<pid>
For example, if the pid was 92564, then in this case the file would look like:
4545
92564
When you specify a file, but not a port then it will choose a free port on your system:
$ harpoon container_manager /path/to/file
Starting the container manager is useful if you want to start it and then run something else that uses it. For example, you could say something like:
#!/bin/bash
set -e
info=$(mktemp)
cleanup() { rm $info; }
trap cleanup EXIT
# container_manager will exit with an error status if we couldn't start
# The container manager. But because we gave it just a file, it'll run the
# web server in the background and the script will continue
harpoon container_manager $info --non-interactive
PORT=$(head -n1 $info)
export HARPOON_CONTAINER_MANAGER="http://localhost:$PORT"
cleanup() {
if ! rm $info; then
echo "Failed to remove temporary file at $info"
fi
curl "$HARPOON_CONTAINER_MANAGER/shutdown"
}
trap cleanup EXIT
# Run tests
bazel test