Did you know ... Search Documentation:
Pack canny_tudor -- prolog/canny/docker.pl
PublicShow source

This module provides an interface to the Docker API, allowing interaction with Docker services through HTTP requests. It defines settings for the Docker daemon URL and API version, and provides a predicate to construct URLs and options for various Docker operations.

It supports operations such as listing containers, creating containers, and checking the Docker system status. The module uses Prolog dictionaries to represent JSON data structures, making it easy to work with the Docker API's responses. It also includes utility predicates for transforming dictionary key-value pairs and constructing paths for API requests. It is designed to be used in conjunction with the HTTP client library to make requests to the Docker API. It provides a flexible way to interact with Docker services, allowing for dynamic construction of API requests based on the specified operations and options.

Docker API Operations

The module supports various Docker API operations, such as:

  • system_ping: Check if the Docker daemon is reachable.
  • container_list: List all containers.
  • container_create: Create a new container.
  • network_create: Create a new network.
  • network_delete: Delete a network.

These operations are defined in the Docker API specification and can be accessed through the docker/3 predicate, which constructs the appropriate URL and options based on the operation and the settings defined in this module.

Example container operations

The following examples demonstrate how to list and create Docker containers using the docker/3 predicate. The first example lists all containers, and the second example creates a new container with a specified image and labels.

?- docker(container_list, Reply).
Reply = [json(['Id'='abc123', 'Image'='ubuntu:latest', ...|...])].
?- docker(container_create, Reply, [post(json(json(['Image'=ubuntu,
   'Labels'=json(['Hello'=world)])))])).
Reply = _{Id:"abc123", Warnings:[]}.

The container_list/2 predicate retrieves a list of all containers, returning a list of dictionaries representing each container. Each dictionary contains information such as the container ID, image, and other metadata. The container_create/3 predicate creates a new container with the specified image and labels. The labels are specified as a JSON object, allowing for flexible tagging of containers with metadata. The reply contains the ID of the created container and any warnings that may have occurred during the creation process. The labels can be used to organise and manage containers based on specific criteria, such as purpose or owner.

Example network operations

The following examples demonstrate how to create and delete a Docker network using the docker/3 predicate. The network is created with a name and labels, and then deleted by its name.

?- docker(network_create(_{name:my_network, labels:_{'my.label':'my-value'}}), A).
A = _{id:"1be0f5d2337ff6a6db79a59707049c199268591f49e3c9054fc698fe7916f9c3", warning:""}.

38 ?- docker(network_delete(my_network), A).
A = ''.

Note that the network_create/2 predicate constructs a network with the specified name and labels, and returns a reply containing the network ID and any warnings. The network_delete/2 predicate deletes the network by its name, returning an empty reply if successful.

Labels can be used to tag networks with metadata, which can be useful for organising and managing Docker resources. The labels are specified as a dictionary with key-value pairs, where the keys and values are strings. The labels are included in the network configuration when creating a network, allowing for flexible and dynamic tagging of Docker resources.

Labels can be used to filter and query networks, making it easier to manage Docker resources based on specific criteria. For example, you can create a network with a label indicating its purpose or owner, and then use that label to find networks that match certain criteria. This allows for more organised and efficient management of Docker resources, especially in larger deployments with many networks and containers.

Restyling Keys

The docker/3 predicate transforms the keys in the input dictionary to CamelCase format using the restyle_key/3 predicate, which applies the Docker-specific CamelCase naming convention to the keys. This transformation is useful for ensuring that the keys in the input dictionary match the expected format for the Docker API, making it easier to work with the API and ensuring compatibility with the expected request format.

The transformation is applied recursively to all key-value pairs in the input dictionary, ensuring that all keys are transformed to the correct format before making the request to the Docker API. The reverse transformation is applied to the reply dictionary, which does not retain the original key names as returned by the Docker API. Label keys are also transformed to CamelCase format, ensuring consistency in the naming convention used for labels in the Docker API requests and responses.

Low-Level HTTP Requests

The module provides a low-level interface to the Docker API, allowing for custom HTTP requests to be made. The docker/3 predicate constructs the URL and options for the specified operation, and uses the http_get/3 predicate to make the request. The options can include HTTP methods, headers, and other parameters as needed for the specific operation.

The url_options/4 predicate is used to construct the URL and options for a specific Docker operation. It retrieves the operation details from the Docker API specification and formats the path according to the specified version and operation. The resulting URL and options can be used with the HTTP client to make requests to the Docker API.

Example usage

The url_options/4 predicate can be used to construct the URL and options for a specific Docker operation. For example, to get the URL and options for the system_ping operation, you can use:

?- [library(http/http_client)].
true.

?- canny_docker:url_options(system_ping, URL, Options),
   http_get(URL, Reply, Options).
URL = [path('/v1.49/_ping'), protocol(tcp), host(localhost), port(2375)],
Options = [method(get), accept(["text/plain"])],
Reply = 'OK'.

For listing containers, you can use:

?- canny_docker:url_options(container_list, URL, Options),
   http_get(URL, Reply, Options).
URL = [path('/v1.49/containers/json'), protocol(tcp), host(localhost), port(2375)],
Options = [method(get), accept(["application/json"])],
Reply = [json(['Id'=..., ...|...])].

For creating a container, you can use:

?- docker(container_create, A, [post(json(json(['Image'=ubuntu,
   'Labels'=json(['Hello'=world])])))]).

This example creates a new Docker container with the specified image and labels. Notice that the post request uses json(json(...)) to specify the JSON body of the request.

author
- Roy Ratcliffe
version
- 0.1.0
 docker(+Ask, -Reply) is det
Issues a request to the Docker API using the specified Ask term and returns the Reply. The Ask term may be a compound specifying the operation to perform together with any required arguments.

The Docker API request comprises:

  • a path with zero or more placeholders,
  • a method,
  • zero or more required or optional search parameters,
  • a JSON body for POST requests.

This implies that, for the least amount of additional information, a request is just a path with a method, e.g., a GET, HEAD or DELETE request. From that point onward, requests grow in complexity involving or more of the following: path placeholders, query parameters, a request body.

The complexity of the request can vary significantly based on the operation being performed and the specific requirements of the Docker API. The docker/2 predicate is designed to handle these variations and provide a consistent interface for interacting with the Docker API. It abstracts away the details of constructing the request and processing the response, allowing users to focus on the high-level operation they want to perform. Path placeholders appear in the first Ask term argument as atomic values. URL query parameters are specified as a list of key-value pairs in the Ask term argument. POST request payloads are specified as a Prolog dictionary as the Ask term.

The Ask term is a compound term that specifies the operation to perform, such as container_list or system_ping. The Reply is a Prolog term that represents the response from the Docker API, which is typically a Prolog dictionary or list, depending on the operation.

The predicate constructs the URL and options based on the operation and the settings defined in this module. It uses the ask/4 predicate to determine the path, method, and any additional options required for the request. The URL is constructed by appending the path to the daemon_url setting, and the HTTP request is made using the http_get/3 predicate from the HTTP client library.

The Reply is then processed to ensure that the keys in the response are transformed to CamelCase format using the restyle_value/3 predicate. This transformation is useful for ensuring that the keys in the response match the expected format for the Docker API, making it easier to work with the API and ensuring compatibility with the expected response format.

Arguments:
Ask- The Ask term specifies the operation to perform, which may include path placeholders, query parameters, and a request body. The Ask term is a compound term that identifies the operation and provides any necessary arguments or parameters for the request. The Ask term can be a simple atom for operations with no arguments, or it can be a more complex term that includes arguments. The Ask term is used to construct the URL and options for the request, allowing for flexible and dynamic construction of API requests based on the specified operation and options.
Reply- The Reply is the response from the Docker API, which is typically a Prolog dictionary or list, depending on the operation. It can also be an atom. The Reply is a Prolog term that represents the data returned by the Docker API after processing the request. It contains the results of the operation, such as a list of containers, the status of a container, or the result of a command.
 docker(+Operation, -Reply, +Options) is det
Makes a request to the Docker API using the specified operation and options. The operation is a string that identifies the Docker API operation to perform, such as container_list or system_ping. The predicate constructs the URL and options based on the operation and the settings defined in this module.

Builds HTTP request options for the Docker API using the base URL from the daemon_url setting. The path and HTTP method are determined by path_and_method/4, and the resulting options are suitable for making requests to the Docker API.

The predicate constructs the URL by concatenating the base URL with the path and method. The daemon_url setting provides the base URL, and the api_version setting specifies the version of the Docker API.

Arguments:
Operation- The operation to perform, which determines the path and method, as well as any additional options.
Reply- The response from the Docker API, which is typically a Prolog dictionary or list, depending on the operation.
Options- This is a list of options that control both how the path is formatted and how the HTTP request is made. For path formatting, options are terms like id(Value) that provide values for placeholders in the path template. For the HTTP request, options can include settings such as headers, authentication, or other parameters supported by the HTTP client.
 docker_path_options(?Operation, -Path, -Options) is semidet
Constructs the Path and Options for a Docker API operation. The predicate retrieves the operation details from the Docker API specification and formats the path according to the default version and operation. The resulting path and options can be used with the HTTP client to make requests to the Docker API.

The predicate uses the docker_path_options/4 predicate to construct the path and options for the specified operation. It retrieves the operation details from the Docker API specification and formats the path according to the specified version and operation. The resulting path and options can be used with the HTTP client to make requests to the Docker API.

build_prune'/v1.49/build/prune'post
config_create'/v1.49/configs/create'post
config_delete'/v1.49/configs/{id}'delete
config_inspect'/v1.49/configs/{id}'get
config_list'/v1.49/configs'get
config_update'/v1.49/configs/{id}/update'post

For container operations, the following paths and options are defined:

container_archive'/v1.49/containers/{id}/archive'get
container_archive_info'/v1.49/containers/{id}/archive'head
container_attach'/v1.49/containers/{id}/attach'post
container_attach_websocket'/v1.49/containers/{id}/attach/ws'get
container_changes'/v1.49/containers/{id}/changes'get
container_create'/v1.49/containers/create'post
container_delete'/v1.49/containers/{id}'delete
container_exec'/v1.49/containers/{id}/exec'post
container_export'/v1.49/containers/{id}/export'get
container_inspect'/v1.49/containers/{id}/json'get
container_kill'/v1.49/containers/{id}/kill'post
container_list'/v1.49/containers/json'get
container_logs'/v1.49/containers/{id}/logs'get
container_pause'/v1.49/containers/{id}/pause'post
container_prune'/v1.49/containers/prune'post
container_rename'/v1.49/containers/{id}/rename'post
container_resize'/v1.49/containers/{id}/resize'post
container_restart'/v1.49/containers/{id}/restart'post
container_start'/v1.49/containers/{id}/start'post
container_stats'/v1.49/containers/{id}/stats'get
container_stop'/v1.49/containers/{id}/stop'post
container_top'/v1.49/containers/{id}/top'get
container_unpause'/v1.49/containers/{id}/unpause'post
container_update'/v1.49/containers/{id}/update'post
container_wait'/v1.49/containers/{id}/wait'post
put_container_archive'/v1.49/containers/{id}/archive'put

For distribution operations, the following paths and options are defined:

distribution_inspect'/v1.49/distribution/{name}/json'get

For exec operations, the following paths and options are defined:

exec_inspect'/v1.49/exec/{id}/json'get
exec_resize'/v1.49/exec/{id}/resize'post
exec_start'/v1.49/exec/{id}/start'post

For image operations, the following paths and options are defined:

image_build'/v1.49/build'post
image_commit'/v1.49/commit'post
image_create'/v1.49/images/create'post
image_delete'/v1.49/images/{name}'delete
image_get'/v1.49/images/{name}/get'get
image_get_all'/v1.49/images/get'get
image_history'/v1.49/images/{name}/history'get
image_inspect'/v1.49/images/{name}/json'get
image_list'/v1.49/images/json'get
image_load'/v1.49/images/load'post
image_prune'/v1.49/images/prune'post
image_push'/v1.49/images/{name}/push'post
image_search'/v1.49/images/search'get
image_tag'/v1.49/images/{name}/tag'post

For network operations, the following paths and options are defined:

network_connect'/v1.49/networks/{id}/connect'post
network_create'/v1.49/networks/create'post
network_delete'/v1.49/networks/{id}'delete
network_disconnect'/v1.49/networks/{id}/disconnect'post
network_inspect'/v1.49/networks/{id}'get
network_list'/v1.49/networks'get
network_prune'/v1.49/networks/prune'post

For node operations, the following paths and options are defined:

node_delete'/v1.49/nodes/{id}'delete
node_inspect'/v1.49/nodes/{id}'get
node_list'/v1.49/nodes'get
node_update'/v1.49/nodes/{id}/update'post

For plugin operations, the following paths and options are defined:

plugin_create'/v1.49/plugins/create'post
plugin_delete'/v1.49/plugins/{name}'delete
plugin_disable'/v1.49/plugins/{name}/disable'post
plugin_enable'/v1.49/plugins/{name}/enable'post
plugin_inspect'/v1.49/plugins/{name}/json'get
plugin_list'/v1.49/plugins'get
plugin_pull'/v1.49/plugins/pull'post
plugin_push'/v1.49/plugins/{name}/push'post
plugin_set'/v1.49/plugins/{name}/set'post
plugin_upgrade'/v1.49/plugins/{name}/upgrade'post
get_plugin_privileges'/v1.49/plugins/privileges'get
secret_create'/v1.49/secrets/create'post
secret_delete'/v1.49/secrets/{id}'delete
secret_inspect'/v1.49/secrets/{id}'get
secret_list'/v1.49/secrets'get
secret_update'/v1.49/secrets/{id}/update'post

For service operations, the following paths and options are defined:

service_create'/v1.49/services/create'post
service_delete'/v1.49/services/{id}'delete
service_inspect'/v1.49/services/{id}'get
service_list'/v1.49/services'get
service_logs'/v1.49/services/{id}/logs'get
service_update'/v1.49/services/{id}/update'post

For session operations, the following paths and options are defined:

session'/v1.49/session'post

For swarm operations, the following paths and options are defined:

swarm_init'/v1.49/swarm/init'post
swarm_inspect'/v1.49/swarm'get
swarm_join'/v1.49/swarm/join'post
swarm_leave'/v1.49/swarm/leave'post
swarm_unlock'/v1.49/swarm/unlock'post
swarm_unlockkey'/v1.49/swarm/unlockkey'get
swarm_update'/v1.49/swarm/update'post

For system operations, the following paths and options are defined:

system_auth'/v1.49/auth'post
system_data_usage'/v1.49/system/df'get
system_events'/v1.49/events'get
system_info'/v1.49/info'get
system_ping'/v1.49/_ping'get
system_ping_head'/v1.49/_ping'head
system_version'/v1.49/version'get

For task operations, the following paths and options are defined:

task_inspect'/v1.49/tasks/{id}'get
task_list'/v1.49/tasks'get
task_logs'/v1.49/tasks/{id}/logs'get

For volume operations, the following paths and options are defined:

volume_create'/v1.49/volumes/create'post
volume_delete'/v1.49/volumes/{name}'delete
volume_inspect'/v1.49/volumes/{name}'get
volume_list'/v1.49/volumes'get
volume_prune'/v1.49/volumes/prune'post
volume_update'/v1.49/volumes/{name}'put
Arguments:
Operation- The operation to perform, which determines the path and method, as well as any additional options.
Path- The path for the operation, which is derived from the Docker API specification.
Options- List of options for the HTTP request, such as method and accept.